Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Итог_Пособие C++.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.03 Mб
Скачать

3.9.2 Абстрактные классы

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

Абстрактные методы – виртуальные методы класса без реализации, иначе они называются чистыми виртуальными функциями и записываются следующим образом:

virtual тип_результата имя_метода(параметры) = 0;

Соответственно, реализацию данного метода в классе писать не надо, но и нельзя создавать объекты такого класса, т.к. в принципе не понятно, что делать, если будет вызван метод без реализации. Классы, содержащие хотя бы один абстрактный метод, называются абстрактными классами. От них нельзя создавать объекты, но их очень удобно использовать при организации иерархии классов как основу для создания целого семейства наследников, имеющих общие свойства. Кстати, отметим, что упоминавшийся уже класс ios из библиотеки iostream является абстрактным классом, который используется для хранения информации, общей для классов istream и ostream.

Для примера реализации абстрактного класса и его потомков снова воспользуемся предметной областью геометрических фигур. Абстрактный класс shape содержит абстрактный метод area (площадь фигуры), который легко реализуется в двух наследниках circle и rectangle. Далее в примере представлены полиморфные функции, которые корректно работают с любой геометрической фигурой (количество потомков класса shape можно существенно расширить).

// Пример 3.5 – иерархия классов геометрических фигур.

#include <iostream>

// абстрактный класс - геометрическая фигура

class shape

{protected:

int x,y;

public:

shape(int _x,int _y);

shape();

virtual double area()=0; // чистая виртуальная функция

// нельзя вычислить площадь абстрактной фигуры

};

// первый наследник - круг

class circle:public shape

{private:

int r;

public:

circle();

circle(int _x, int _y, int _r);

double area() override;

};

// второй наследник - прямоугольник

class rectangle:public shape

{private:

int w,h;

public:

rectangle();

rectangle(int _x, int _y, int _w, int _h);

double area() override;

};

// реализация конструкторов предка

shape::shape(int _x, int _y)

{x=_x;y=_y;}

shape::shape()

{x=1;y=1;}

// методы circle

circle::circle():shape(),r(100){}

circle::circle(int _x, int _y, int _r):shape(_x,_y),r(_r){}

double circle::area(){return 3.1415926*r*r;}

// методы rectangle

double rectangle::area(){return w*h;}

rectangle::rectangle():shape(){w=100;h=100;}

rectangle::rectangle(int _x, int _y, int _w, int _h):shape(_x,_y),w(_w),h(_h){}

// Теперь мы можем писать универсальные функции для разных видов фигур

// например, сравниваем площади двух фигур

double compare(shape& x, shape& y){return x.area()-y.area();}

// находим максимальную площадь в массиве из разных фигур

double maxarea(shape **x, int n)

{double m=x[0]->area();

for(int i=1;i<n;i++)

if (x[i]->area()>m) m=x[i]->area();

return m;

}

int main(){

shape *p[2];

p[0]=new circle(100,100,50);

p[1]=new rectangle(100,100,20,30);

for (int i=0;i<2; i++)

std::cout<<p[i]->area()<<std::endl;

std::cout<<maxarea(p,2)<<std::endl;

std::cout<<compare(*p[0],*p[1])<<std::endl;

}

В данной главе мы рассмотрели самые основные понятия объектно-ориентированного программирования на C++. В следующих главах эта тема будет существенно расширена.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]