Пусть имеется некоторый класс со своими свойствами и методами. На основе этого класса можно создать новый класс, связав его с исходным классом отношением наследования. Исходный класс называют родительским или суперклассом, а производный от него – дочерним или подклассом. Отношение наследования между ними означает, что в дочернем классе можно использовать свойства и методы базового родительского класса, никак их не определяя. Говорят, что эти методы и свойства наследуются из родительского класса.
Отношения наследования надо устанавливать, если для двух классов справедливым является следующее высказывание: «класс В является разновидностью класса А» (класс В “is-a” класс А). Этим отношение наследования принципиально отличается от агрегации и композиции. Например, если двигатель есть часть автомобиля, то уж никак двигатель не является разновидностью автомобиля. С другой стороны, автомобиль есть разновидность транспортного средства, но никак не его часть!
При создании дочернего подкласса в него можно добавить новые свойства и методы, которых не было в родительском классе. Тем самым дочерний подкласс расширяет набор свойств и методов своего родителя. На основе одного родителя можно создать любое количество дочерних подклассов. У всех дочерних подклассов есть что-то общее, определяемое унаследованными свойствами и методами, и в то же время каждый класс индивидуален,так как содержит свои собственные свойства и методы.
в подклассе не определяются
унаследованные свойства
унаследованные методы
новые свойства
новые методы
переопределенные методы
Дочерний подкласс 2
унаследованные свойства
унаследованные методы
новые свойства
новые методы
переопределенные методы
Дочерний подкласс 1
Дочерний подкласс, в свою очередь, может выступать в качестве базового родительского класса, на основе которого можно создать свои дочерние подклассы. В итоге получается иерархическая древовидная структура классов, часто называемая библиотекой классов. На верхних уровнях этой иерархии находятся наиболее общие классы с относительно небольшим числом свойств и методов. Чем ниже класс в иерархии, тем больше он имеет свойств и методов и, тем самым, носит более конкретный характер. Классы верхних уровней часто объявляются абстрактными. Эти классы нужны для придания общности нижележащим подклассам.
Рассмотренный тип наследования называют простым наследованием. В этом случае дочерние подклассы могут иметь только одного родителя. Если родителей может быть несколько, то наследование называют множественным. Множественное наследование в чистом виде реализовано только в языке С++. В случае множественного наследования вместо древовидной иерархии возникает иерархия в виде ориентированного графа:
Множественное наследование является очень мощным механизмом, но при его практическом использовании появляются трудности, связанные с неоднозначностью путей наследования. По этой причине в языке Java и в языках платформы .NET реализовано только простое наследование, но в качестве альтернативного механизма предложен более простой, по сравнению с множественным наследованием, механизм интерфейсных классов (см. раздел 4.1 пособия).
В дальнейшем основное внимание будет уделено библиотекам классов, которые построены на принципе простого наследования. Именно так построены стандартные библиотеки классов, поддерживающие языки Java, Delphi Pascal и платформу .NET. В этих библиотеках на самом верхнем уровне находится единственный класс, который является общим предком абсолютно любых классов, как стандартных, так и создаваемых программистом при разработке объектной программы. В этом классе объявляются свойства и методы, наследуемые всеми классами. В языках Java и С# этот класс называют Object, в Delphi Pascal – TObject. Несмотря на общность названия, структура этих классов в разных языках различная.
В чем же состоит мощь принципа наследования? Для трех-четырех классов, связанных отношением наследования, вряд ли стоит ожидать каких-то существенных преимуществ. Мощь иерархии классов проявляется для больших разветвленных наборов, содержащих десятки и сотни взаимосвязанных классов. В такой иерархии можно найти один или несколько наиболее подходящих для решения конкретной задачи классов, причем если какой-то существующий класс не полностью отвечает необходимым требованиям, на его основе можно легко создать класс-потомок, добавив недостающие свойства и методы и даже изменив реализацию некоторых из унаследованных методов. В целом это существенно сокращает время разработки новой программы, позволяет максимально использовать ранее созданный и отлаженный код, повышает надежность программы и облегчает ее модернизацию.
Механизм наследования между классами в разных языках включается очень легко и практически одинаково: имя родительского класса прописывается в заголовке нового класса.