- •Теоретические основы объектно-ориентированного программирования
- •Объектная декомпозиция
- •Диаграмма обслуживания автомашин на бензоколонке
- •Диаграмма объектов имитационной модели бензоколонки
- •Объектная декомпозиция Блока колонок: 1 - когда освободится колонка? 3 - колонка свободна? 2 - освободить колонку 4 - занять колонку
- •Диаграмма объектов графического редактора
- •Диаграмма состояний интерфейса пользователя программы «Записная книжка»
- •Диаграмма объектов предметной области программы «Записная книжка»
- •Обозначение ассоциации: а - с указанием имени ассоциации и ее направления; б - с указанием имен ролей; в - с указанием множественности
- •Контекстная диаграмма классов программы «Записная книжка»
- •Объекты и сообщения
- •Типы отношений между объектами
- •Соответствие объекта-абстракции классу и объектам-переменным
- •Основные средства разработки классов
- •Иерархии классов при различных видах наследования
- •Иерархия классов Окно и Окно_меняющее_цвет
- •Иерархия классов Окно и Окно_с_текстом
- •Иерархия классов при сложном полиморфизме
- •Необходимость позднего связывания
- •Реализация механизма позднего связывания
- •Необходимость явного указания типа объекта, адресуемого указателем родительского класса
- •Вид окна сообщения
- •Структура полей класса Сообщение
- •Дополнительные средства и приемы разработки классов
- •Организация стека вызовов
- •Определение класса
- •Организация списка объектов с использованием статических компонентов класса
- •Конструкторы и деструкторы
- •Наследование
- •Иерархия классов Целое число - Вещественное число
- •Диаграмма классов с наследованием от двух классов и объектным полем
- •Иерархия с многократным наследованием
- •Исключения
- •1. Динамическая проверка типа объекта:
- •2. Динамическое переопределение типа объекта:
- •3. Динамическое определение типа объекта:
-
Иерархия классов Целое число - Вещественное число
Множественное наследование. Язык C++ позволяет осуществлять наследование не только от одного, но и одновременно от нескольких классов. Такое наследование получило название множественного. При множественном наследовании производный класс включает произвольное количество базовых классов. Описание производного класса в этом случае выглядит следующим образом:
class <имя производного класса>:
<вид наследования><имя базового класса 1>, <вид наследования><имя базового класса 2>,
<вид наследования><имя базового класса n>{...};
Вид наследования определяет режим доступа к компонентам каждого из базовых классов. Базовые классы создаются в том порядке, в котором они перечислены в списке базовых классов при объявлении производного класса. Если конструкторы базовых классов не имеют аргументов, то производный класс может не иметь конструктора. При наличии у конструктора базового класса одного или нескольких аргументов, каждый производный класс обязан иметь конструктор. Чтобы передать аргументы в базовый класс, нужно определить их после объявления конструктора производного класса следующим образом:
<имя конструктора производного класса>(<список аргументов>):
<имя конструктора базового класса 1>(<список аргументов>),
<имя конструктора базового класса n>(<список аргументов>) {<тело конструктора производного класса>}
Список аргументов, ассоциированный с базовым классом, может состоять из констант, глобальных параметров и/или параметров для конструктора производного класса.
Последовательность активизации конструкторов такая же, как и для случая единственного базового класса: сначала активизируются конструкторы всех базовых классов в порядке их перечисления в объявлении производного класса, затем конструкторы объектных полей и в конце конструктор производного класса.
-
Наследование от двух базовых классов. В данном примере класс twonasl наследуется от классов integral и rational и включает объект класса fixed (Рис. 3.3.).
Объект класса twonasl состоит из следующих полей:
• поля numfx, унаследованного от класса integral (описанного public, наследованного private, следовательно, private) и инициализированного случайным числом в диапазоне от -50 до 49;
• полей num и с, унаследованных от класса rational (описанных public, наследованных public, следовательно, public) и инициализированных числами 20 и символом «R», причем инициализация поля с в конструкторе класса rational не предусмотрена, поэтому она выполняется в теле конструктора класса twonasl;
-
Диаграмма классов с наследованием от двух классов и объектным полем
• объекта класса fixed с именем numfix, включающего внутреннее поле numfx, которое недоступно в классе twonasl и инициализируется числом 50.
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
class fixed
{ int numfx;
public: fixed(int v):numfx(v) {cout<<" вызов конструктора fixed\n";}
};
class integral
{ public: int numfx;
integral(int va):numfx(va) {cout<<" вызов конструктора integ\n"; }
};
class rational
{public: char c; int num;
rational (int vn):num(vn) { cout<< " вызов конструктора rational\n ";}
};
class twonasl:private integral, // наследование в защищенном режиме
public rational // наследование в открытом режиме
{ private: fixed numfix; // объектное поле
public:
twonasl (int nfx,int nm,char vc,int pnfx):
integral(nfx), rational(nm), numfix(pnfx)
{ cout<< " вызов конструктора twonasl\n "; c=vc; } /* инициализация поля базового класса в теле конструктора производного класса */
int get(void) // метод, возвращающий значение внутреннего поля,
{ return numfx;} // унаследованного от класса integral по private
};
void main()
{ clrscr(); randomize;
int r=random(100)-50; twonasl aa(r,20, 'R',50);
cout<<aa.get()<<" "<<aa.c<<" "<<aa.num<<endl; getch();}
В результате выполнения программы мы получаем следующую цепочку обращений к конструкторам:
вызов конструктора integ
вызов конструктора rational
вызов конструктора fixed
вызов конструктора twonasl
и содержимое полей numfx (класса integral), с и num, доступных в классе twonasl:
-49 R 20
Виртуальное наследование. При множественном наследовании базовый класс не может быть указан в производном классе более одного раза. Однако возможна ситуация, когда производный класс при наследовании от потомков одного базового класса многократно наследует одни и те же компоненты базового класса (Рис. 3.4.). Иными словами, производный класс будет содержать несколько копий полей одного базового класса.