Природа наследования
В языках программирования наследование означает, что поведение и элементы данных, связанные с производным классом, всегда являются расширением характеристик, связанных с родительскими классами. Подкласс имеет все характеристики родительского класса и, кроме того, дополнительные характеристики.
С другой стороны, поскольку производный класс считается более специализированной (или ограниченной) формой родительского класса, он также, в определенном смысле, будет сужением родительского класса. Это диалектическое противоречие между наследованием как расширением и наследованием как сужением является источником большой силы, присущей данному отношению, и в то же время вызывает некоторую путаницу.
Природа наследования |
451 |
Наследование всегда транзитивно, следовательно, класс может наследовать черты суперклассов, отстоящих от него на несколько уровней. Например, если Сеттер — это подкласс класса ОхотничьиСобаки, считающегося подклассом класса Собаки, а собаки являются подклассом класса Млекопитающие, то класс Сеттер наследует характеристики и охотничьих собак, и собак вообще, и всех млекопитающих Млекопитающие. ПРИМЕЧАНИЕ --------------------------------------------------------------------------------------------------- Отношение R называется транзитивным, если для любых a, Ь, c из aRb и bRc следует aRc. |
Усложняющим моментом в механизме наследования является то обстоятельство, что подклассы могут переопределять поведение, унаследованное от родительского класса. Например, класс Сеттер переопределяет операцию отображатьВнешний- Вид( ), унаследованную от класса млекопитающих, поскольку внешний облик сеттеров очень специфичен. В данном разделе мы коротко затронем лишь некоторые аспекты переопределения. Существует эмпирическое правило для проверки того, связаны ли два понятия отношением наследования. Оно называется проверкой «is-a» («является»). Тест «является» говорит, что если понятие A должно быть связано наследованием с понятием B, попробуйте произнести «А является В» (по-английски: «A(n) A isa(n) B»). Если ваш слух эта фраза не коробит, тогда наследование, скорее всего, уместно в данной ситуации. К примеру, вполне разумны следующие высказывания: ? Птица является Животным (A Bird is an Animal). ? Кот является Млекопитающим (A Cat is a Mammal). ? Яблочный Пирог является Пирогом (An Apple Pie is a Pie). ? Текстовое Окно является Окном (A Text Window is a Window). ? Шар является Графическим Объектом (A Ball is a Graphical Object). ? Целый Массив является Массивом (An Integer Array is an Array). С другой стороны, следующие высказывания по той или иной причине кажутся странными и наследование, наверное, здесь не применимо: ? Птица является Млекопитающим. ? Яблочный Пирог является Яблоком. ? Двигатель является Автомобилем. ? Текстовое Окно является Кнопкой. ? Целый Массив является Целой Величиной. Конечно, бывают ситуации, когда наследование применимо, даже если тест «является» не пройден. Тем не менее в большинстве случаев он считается хорошим индикатором целесообразности наследования. Главными причинами применения наследования полагают: ? Наследование как средство повторного использования программного кода. Поскольку класс-потомок может наследовать поведение класса-родителя, исчезает |
452 Глава 16. Объектно-ориентированное и аспектно-ориентированное программирование |
необходимость заново писать программный код для потомка. Это позволяет существенно сократить количество кода, требуемое для разработки новой идеи. ? Наследование как средство повторного использования идеи (концепции, понятия). Это происходит, когда класс-потомок переопределяет поведение, доставшееся ему от родителя. Хотя код реализации у потомка отличается от родительского, но идея какого-то метода у них общая. Следовательно, опять экономятся усилия, необходимые для новой разработки. |