236.00K
Категория: ПрограммированиеПрограммирование

Полиморфизм. Лекция №17

1.

Лекция № 17
Полиморфизм

2.

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

3.

Класс телефон
class phone
{
char number[15];
public:
void ring(void);
phone(char *num);
};
...
int main(void)
{
phone SOT1("89136789894");
phone TEL1("83822909090");
getch(); return 0;
}
SOT1.ring();
TEL1.ring();

4.

Класс телефон
Не различаются сотовые и стационарные.
Можно сделать наследование классов.
Класс phone – базовый
sotov и station - производные

5.

Класс телефон с наследованием (1)
class phone
{
public:
void ring(void) {printf("Ring ring ring.....\n");}
phone(char *num) {strcpy(number, num); }
protected:
char number[15];
};
class sotov_phone : public phone
{
public:
void info(void) {printf("Mobile :-)");}
sotov_phone(char *num) : phone(num){};
int S_3G;
};

6.

Класс телефон с наследованием (2)
class station_phone : public phone
{
public:
void info(void) {printf("Stationary :-P");}
station_phone(char *num) : phone(num){};
int type;
};
int main(void)
{
sotov_phone SOT1("89136789894");
SOT1.ring();
station_phone TEL1("83822909090"); TEL1.ring();
getch();
}

7.

Класс телефон
Различие классов только в методе info().
Хотелось бы один объект,
который бы менял свой тип при необходимости.
Создадим полиморфный объект телефон.

8.

Указатели и наследование
В общем случае указатель одного типа не может
указывать на объект другого типа.
Исключение - производные классы.
Указатель на базовый класс может указывать на
объект производного класса
(обратное не имеет места).
Не может использоваться для доступа к членам,
специфическим для производного класса,
пока не выполнено приведение типов.

9.

Виртуальная функция
Виртуальная функция объявляется в базовом классе
с использованием ключевого слова virtual.
Виртуальные функции в комбинации с производными
типами позволяют языку С++ поддерживать
полиморфизм времени исполнения.
Полиморфизм позволяет переопределять функции
базового класса в классах-потомках с тем, чтобы
иметь их версию применительно к данному
конкретному классу.
«один интерфейс — множество методов».

10.

Полиморфный телефон (1)
class phone
{
public:
virtual void info(void){printf("Base type......");}
void ring(void)
{printf("Ring ring ring.....\n");}
phone(char *num)
{strcpy(number, num); }
protected:
char number[15];
};
class sotov_phone : public phone
{
public:
void info(void) {printf("Mobile :-)\n");}
sotov_phone(char *num) : phone(num){};
int S_3G;
};

11.

Полиморфный телефон (2)
class station_phone : public phone
{
public:
void info(void) {printf("Stationary :-P\n");}
station_phone(char *num) : phone(num){};
int type;
};
int main(void)
{
phone *PH;
sotov_phone SOT1("89136789894");
SOT1.ring();
station_phone TEL1("83822909090"); TEL1.ring();
}
PH = &SOT1;
((sotov_phone *)PH)->S_3G=1;
PH->info();
PH = &TEL1;
getch();
((station_phone *)PH)->type=3; PH->info();

12.

Ограничения виртуальной функции
При перегрузке функции число и тип параметров
должны быть различными. При переопределении
виртуальной функции интерфейс функции должен в
точности соответствовать прототипу.
Виртуальная функция должна быть членом, а не
другом класса. Тем не менее виртуальная функция
может быть другом другого класса.
Деструктор может быть виртуальным,
но конструктор виртуальным быть не может.

13.

Пример Массив фигур (1)
class figure
{
protected:
float x, y;
public:
void set_dim( float i, float j=0) {x = i; y = j;}
virtual void info() {}
};
class triangle : public figure
{
public:
void info() {printf("Triangle =
};
%f\n",0.5*x*y);}
class square : public figure
{
public:
void info() {printf("Square = %f\n",x*y);}
};

14.

Пример Массив фигур (2)
class circle : public figure
{
public:
void info() {printf("Square = %f\n",x*x*3.14);}
};
int main (void)
{
figure *p[3];
triangle t; /* ñîçäàíèå îáúåêòîâ ïîðîæäåííûõ òèïîâ */
square s;
circle c;
p[0] = &t; p[0]->set_dim(10.0, 5.0); p[0]->info();
p[1] = &s; p[1]->set_dim(10.0, 5.0); p[1]->info();
p[2] = &c; p[2]->set_dim(2.0);
p[2]->info();
getch();
return 0;
}

15.

Чисто виртуальная функция
Когда виртуальная функция не переопределена в
производном классе, то при вызове ее в объекте
производного класса вызывается версия из базового
класса.
Иногда не имеет смысла определять виртуальную
функцию в базовом классе. Например, объекты
производных типов могут настолько сильно
отличаться, что им не нужно будет использовать
метод базового класса.
Можно создать чисто виртуальную функцию, которая
не содержит операторов.

16.

Чисто виртуальная функция
Когда виртуальная функция не переопределена в
производном классе, то при вызове ее в объекте
производного класса вызывается версия из базового
класса.
class figure
{
float х, у;
public:
void set_dim(float i, float j=0)
{
x = i; y = j;
}
virtual void show_area() = 0; // чисто виртуальная
};
English     Русский Правила