Лекция
Привет, сегодня поговорим про множественное наследование, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое множественное наследование, проблема ромба , проблема алмаза , настоятельно рекомендую прочитать все из категории С++ (C plus plus).
множественное наследование — свойство, поддерживаемое частью объектно-ориентированных языков программирования, когда класс может иметь более одного суперкласса (непосредственного класса-родителя), интерфейсы поддерживают множественное наследование во многих языках программирования. Эта концепция является расширением «простого (или одиночного) наследования» (англ. single inheritance), при котором класс может наследоваться только от одного суперкласса.
В список языков, поддерживающих множественное наследование, входят: Io, Eiffel, C++, Dylan, Python, некоторые реализации классов JavaScript (например, dojo.declare), Perl 6, Curl, Common Lisp (благодаря CLOS), OCaml, Tcl (благодаря Incremental Tcl) , а также Object REXX (за счет использования классов-примесей).
рис Типы наследования
C++ требует, чтобы программист указал, элемент какого из родительских классов должен использоваться, то есть «Worker::Person.Age». C++ не поддерживает явно повторяемое наследование, так как отсутствует способ определить какой именно суперкласс следует использовать (смотри критику). C++, также, допускает создание единственного экземпляра множественного класса благодаря механизму виртуального наследования (например, «Worker::Person
» и «Musician::Person
» будут ссылаться на один и тот же объект).
Класс может иметь несколько непосредственных базовых классов
class A1{. . .};
class A2{. . .};
class A3{. . .};
class B : public A1,public A2,public A3{. . .};
Такое наследование называется множественным. При множественном наследовании никакой класс не может больше одного раза использоваться в качестве непосредственного базового. Однако класс может больше одного раза быть непрямым базовым классом.
class X{. . . f(); . . .};
class Y : public X{. . .};
class Z : public X{. . .};
class A : public Y,public Z{. . .};
Имеем следующую иерархию классов (и объектов):
Такое дублирование класса соответствует включению в производный объект нескольких объектов базового класса. В этом примере существуют два объекта класса Х. Для устранения возможных неоднозначностей нужно обращаться к конкретному компоненту класса Х, используя полную квалификацию
Y : : X : : f() или Z : : X : : f)
Пример.
Чтобы устранить дублирование объектов непрямого базового класса при множественном наследовании, этот базовый класс объявляют виртуальным.
Теперь класс А будет включать только один экземпляр Х, доступ к которому равноправно имеют классы Y и Z.
Пример 2.7.1
Здесь
объект класса base занимает в памяти 15 байт:
4 байта - поле int;
2 байт - поле char;
10 байт - поле char[10];
объект класса abase занимает в памяти 79 байт:
8 байт - поле double;
15 байт - поля базового класса base;
2 байта - для связи в иерfрхии виртуальных классов;
объект класса bbase занимает в памяти 21 байт:
4 байта - поле float;
15 байт - поля базового класса base; 2 байта - для связи в иерархии виртуальных классов;
объект класса top занимает h памяти 35 байт:
4 байта - поле long;
10 байт - данные и связи abase;
6 байт - даvные и связи bbase;
15 байт - поля базового класса base;
Если при наследовании base в классах abase и bbase базовый класс сделать не виртуальным, то результатb будут такими:
объект класса base занимает в памяти 15 байт
объект класса abase занимает в памяти 26 байта (нет 2-х байтов для связи);
объект класса bbase занимает в памяти 59 байт (нет 2-х байтов для связи);
объекv класса top занимает в памяти 46 байт (объект base входит дважды).
« Проблема алмаза » (иногда называемая «Смертельным алмазом смерти» ) - это неоднозначность, которая возникает, когда два класса B и C наследуются от A, а класс D наследуется от B и C. Об этом говорит сайт https://intellect.icu . метод в A, который B и C переопределили , а D не переопределяет его, то какую версию метода наследует D: версию B или версию C?
Например, в контексте разработки программного обеспечения с графическим пользовательским интерфейсом класс может наследовать как классы (для внешнего вида) и (для функциональности / обработки ввода), так и классы, и оба они наследуются от класса. Теперь, если метод вызывается для объекта и в классе нет такого метода, но есть переопределенный метод в или (или в обоих), какой метод следует в конечном итоге вызвать?
Это называется «алмазной проблемой» из-за формы диаграммы наследования классов в этой ситуации. В этом случае класс A находится наверху, B и C отдельно под ним, а D соединяет их вместе внизу, образуя ромбовидную форму.
В языках есть разные способы решения этих проблем повторного наследования.
D
объект фактически будет содержать два отдельных A
объекта, и использование A
членов должно быть правильно определено. Если наследование от A
до B
и наследование от A
до C
помечены как « virtual
» (например, « class B : virtual public A
»), C ++ уделяет особое внимание созданию только одного A
объекта, и использование A
членов работает правильно. Если виртуальное наследование и невиртуальное наследование смешаны, существует один виртуальный A
и A
невиртуальный путь для каждого невиртуального пути наследования A
. C ++ требует явного указания, из какого родительского класса вызывается функция, которая будет использоваться, т.е.Worker::Human.Age
. C ++ не поддерживает явное повторное наследование, поскольку не было бы возможности определить, какой суперкласс использовать (т. Е. Наличие класса более одного раза в одном списке производных [класс Dog: public Animal, Animal]). C ++ также позволяет создавать один экземпляр множественного класса с помощью механизма виртуального наследования (т.е. он будет ссылаться на один Worker::Human
и Musician::Human
тот же объект).Множественное наследование критикуется за следующие проблемы, возникающие в некоторых языках, в частности, C++:
Множественное наследование в языках с конструкторами в стиле C++/Java усиливает проблему наследования конструкторов и последовательностей конструкторов, таким образом создавая проблемы с поддержкой и расширяемостью в этих языках. Объекты в отношениях наследования со значительно отличающимися методами конструирования довольно трудны для реализации в рамках парадигмы последовательности конструкторов.
Тем не менее, существуют языки, обрабатывающие эти технические тонкости (например Eiffel).
Существует мнение, что множественное наследование — это неверная концепция, порожденная неверным анализом и проектированием. В частности, для приведенного выше примера справедлив следующий вариант проектирования. Класс Person включает в себя один и более объектов класса Profession. Классы Student и Musician наследуют от Profession. Таким образом, StudentMusician будет представлен объектом класса Person содержащим объекты класса Student и Musician. Формально множественное наследование можно перепроектировать путем введения класса, являющегося «метаклассом» классов, от которых должно происходить множественное наследование. В приведенном примере таким метаклассом является Profession — профессия.
В общем, мой друг ты одолел чтение этой статьи об множественное наследование. Работы впереди у тебя будет много. Смело пиши комментарии, развивайся и счастье окажется в твоих руках. Надеюсь, что теперь ты понял что такое множественное наследование, проблема ромба , проблема алмаза и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории С++ (C plus plus)
Из статьи мы узнали кратко, но содержательно про множественное наследование
Комментарии
Оставить комментарий
С++ (C plus plus)
Термины: С++ (C plus plus)