Скачиваний:
313
Добавлен:
28.03.2021
Размер:
378.53 Кб
Скачать

43. Методы классов и множественное наследование. Неопределенности при множественном наследовании и способы её разрешения.

При множественном наследовании производный класс наследует данные и методы базовых классов.

При применении множественного наследования возможно возникновение нескольких конфликтных ситуаций. Первая − конфликт имен методов или атрибутов нескольких базовых классов:

Неопределённость можно устранить, явно указав, какому из базовых классов принадлежит вызываемая функция: A:fun() или B:fun()

Вторая проблема возникает при многократном включении некоторого базового класса:

class A{ public: void fun(){}};

class B : public A{ // компоненты класса В };

class C : public A{ // компоненты класса С };

class D : public B, public C { };

Проблема состоит в том, что при создании объекта класса D создаются два (одинаковых) объекта базового класса A (для объектов класса B и C соответственно). Решение этой проблемы состоит в использовании виртуального наследования

44. Конструкторы при множественном наследовании. Конструкторы без аргументов и конструкторы с аргументами при множественном наследовании.

Конструкторы базовых классов вызываются в том порядке, в котором они указаны в списке при объявлении класса.

В общем случае, когда используется список базовых классов, их конструкторы вызываются сле­ва направо. Деструкторы вызываются в обратном порядке — справа налево.

Важно понимать, что аргументы для конструктора базового класса передаются через аргументы, принимаемые конструктором производного класса. Поэтому, даже если конструктор производного класса не использует никаких аргументов, он, тем не менее, должен объявить один или несколько аргументов, если базовый класс принимает один или несколько аргументов. В этой ситуации аргументы, передаваемые производному классу, "транзитом" передаются базовому.

Конструктор без аргументов вызывает конструкторы базовых классов.

Class A: public B, public C { A():B():C(){…} }

Конструктор с аргументами вызывает конструкторы базовых классов и передаёт им некоторые значения

Class A: public B, public C{ A(int a, int b, string c):B(b, c):C(a) {…} }

45. Связь включения. Классы в классах. Композиция и наследование. Роль наследования при разработке программ.

Отношение включения — реализует логические связи типа «является составной частью».(“имеет”)

Есть два варианта включения объекта типа X в класс A (предпочтительно 1ый):

  1. Объявить в классе А член типа Х: class A { X x; ...};

  2. Объявить в классе А член типа X* или X&: class A { X *p; X &r; ... };

Первый эффективнее и меньше подвержено ошибкам, так как связь между содержащимся и содержащим объектами описывается правилами конструирования и уничтожения. Имея объекты, включающие другие объекты, мы создаем иерархию объектов. Она является альтернативой и дополнением к иерархии классов.

Открытое наследование: Оно говорит, что все, что справедливо для базового класса справедливо и для его наследника. Именно с его помощью мы получаем полиморфное поведение, абстрагируемся от конкретной реализации классов, имея дело лишь с абстракциями (интерфейсами или базовыми классами) и не обращаем внимание на детали реализации. Наследование — это когда класс-наследник имеет все поля и методы родительского класса, и, как правило, добавляет какой-то новый функционал или/и поля. Наследование описывается словом «является».

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

Преимущества композиции перед наследованием: 1. Нет конфликта имён, возможного при наследовании. 2. Возможность смены агрегируемого объекта в runtime. 3. Полная замена агрегируемого объекта в классах, производных от класса, включающего агрегируемый объект.

По сути, наследование позволяет расширять поведение базового (или родительского) класса, наследуя основную функциональность в производном подклассе (также именуемом дочерним классом).

Т.е. наследование представляет собой процесс, в ходе которого один объект приобретает свойства другого объекта. Это очень важный процесс, поскольку он обеспечивает принцип иерархической классификации. Если вдуматься, то большая часть знаний поддаётся систематизации благодаря иерархической классификации по нисходящей. Если не пользоваться иерархиями, то для каждого объекта пришлось бы явно определять все его свойства.

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