Similar presentations:
Полиморфизм. Лекция №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; // чисто виртуальная
};