Множественное наследование.
Объектно-ориентированное программирование
He. Student: Name; // правильно Продолжая анализ полученной иерархии, заметим, что работающий студент имеет всего одно имя. В результате объект класса Student_Worker должен использовать единственную копию элемента Name, унаследованную от Person. В результате приходим к ромбовидной структуре наследования для класса Student_Worker, представленной на рис 4.2. Одним из механизмов задания такого… Читать ещё >
Множественное наследование. Объектно-ориентированное программирование (реферат, курсовая, диплом, контрольная)
Рассмотрим две проблемы, которые возникают при множественном наследовании: конфликт имен между суперклассами и повторное наследование.
Конфликт имен происходит тогда, когда в двух или более суперклассах случайно оказывается элемент (переменная или операция) с одинаковым именем.
Пример. Определим абстракцию «Работающий студент». Для этого введем более общие абстракции «Работник» и «Студент». Абстракция «Работающий студент» будет наследовать компоненты обеих общих абстракций.
class Worker {.
public:
intID_profession; // код профессии.
char* Name; // имя.
};
class Student {.
public:
intID_university; // код университета.
char* Name; // имя.
};
class Student_Worker: public Student, public Worker {. .. };
Рассмотрим последовательность действий.
Student_Worker He;
.. .
He.ID_profession; // правильно.
He.Name; // неправильно — двусмысленно Конфликт имен элементов подкласса может быть разрешен полной квалификацией имени члена класса, т. е. к именам добавляют префиксы, которые указывают имена тех классов, откуда они пришли.
He.Worker: Name; // правильно Повторное наследование возникает тогда, когда при задании более чем одного базового класса какой-либо класс дважды является базовым для другого класса.
Продолжим пример с работающим студентом. Анализируя глубже полученную иерархию наследования, мы обнаружим, что и работник, и студент имеют ряд общих признаков, в частности, имя. Разумно ввести еще более общую абстракцию «Человек» .
class Person {.
public:char* Name; // имя.
}.
class Worker: public Person {.
public:int ID_profession; // код профессии.
}.
class Student: public Person {.
public:int ID_university; // код университета.
}.
Наследственная иерархия класса Student_Worker представлена на рис. 4.1.
Рис. 4.1 Наследственная иерархия класса Student_Worker
Для доступа к одной из копий унаследованного элемента необходимо воспользоваться явной квалификацией, т. е. добавить к его имени префикс в виде имени класса-источника.
He.ID_profession; // правильно.
He.Name; // неправильно — двусмысленно.
He.Person: Name; // неправильно — двусмысленно.
He.Worker: Name; // правильно.
He.Student: Name; // правильно Продолжая анализ полученной иерархии, заметим, что работающий студент имеет всего одно имя. В результате объект класса Student_Worker должен использовать единственную копию элемента Name, унаследованную от Person. В результате приходим к ромбовидной структуре наследования для класса Student_Worker, представленной на рис 4.2.
Рис. 4.2 Ромбовидная структура наследования для класса Student_Worker
Одним из механизмов задания такого совместного использования является виртуальный базовый класс. Виртуальный базовый класс в производном классе представлен одним и тем же (совместно используемым) объектом. Для задания виртуального наследования используется синтаксис следующего примера.
class Person {.. .};
class Worker: public virtual Person {.. .};
class Student: public virtual Person {.. .};
class Student_Worker: public Student, public Worker {... };