Главная » Java » Одиночное и множественное наследование

0

В языке Java новый класс может расширять всего один суперкласс — такая модель носит название одиночного наследования. Расширение класса означает, что новый класс наследует от своего суперкласса не только контракт, но и реализацию. В некоторых объектно-ориентированных языках используется множественное наследование, при котором новый класс может иметь два и более суперклассов.

Множественное наследование оказывается полезным в тех случаях, когда требуется наделить класс новыми возможностями и при этом сохранить большую часть (или все) старых свойств. Однако при наличии нескольких суперклассов возникают проблемы, связанные с двойственным наследованием. Например, рассмотрим следующую иерархию типов:

Обычно такая ситуация называется “ромбовидным наследованием”, и в ней нет ничего плохого — подобная структура встречается довольно часто. Проблема заключается в наследовании реализации. Если класс W содержит открытое поле goggin и у вас имеется ссылка на объект типа Z с именем zref, то чему будет соответствовать ссылка zref.goggin? Будет ли она представлять собой копию goggin из класса X, или из класса Y, или же X и Y будут использовать одну копию goggin, поскольку в действительности  W входит в Z всего один раз, хотя Z одновременно является и X, и Y?

Чтобы избежать подобных проблем, в Java используется объектно-ориентированная модель с одиночным наследованием.

Одиночное наследование способствует правильному проектированию. Проблемы множественного наследования возникают из расширения классов при их реализации. Поэтому Java предоставляет возможность наследования контракта без связанной с ним реализации. Для этого вместо типа class используется тип interface.

Таким образом, интерфейсы входят в иерархию классов и наделяют Java возможностями множественного наследования.

Классы, расширяемые данным классом, и реализованные им интерфейсы совместно называются его супертипами; с точки зрения супертипов, новый класс является подтипом. В понятие “полного типа” нового класса входят все его супертипы, поэтому ссылка на объект класса может использоваться полиморфно — то есть всюду, где должна находиться ссылка на объект любого из супертипов (класса или интерфейса). Определения интерфейсов создают имена типов, подобно тому как это происходит с

именами классов; вы можете использовать имя интерфейса в качестве имени переменной и присвоить ей любой объект, реализующий данный интерфейс.

Источник: Арнольд К., Гослинг Д. – Язык программирования Java (1997)

По теме:

  • Комментарии