110 likes | 271 Views
С++, начала ООП. Семинар 3 Рябова Анна Сергеевна ryabova.anna@gmail.com. Наследование. Расширение функциональности без копипаста Не испортим то, что уже работает Дети сохраняют поля и методы родителя. Наследование. #include <string> #include<iostream> class Movie // Базовый класс {
E N D
С++, начала ООП Семинар 3 Рябова Анна Сергеевна ryabova.anna@gmail.com
Наследование • Расширение функциональности без копипаста • Не испортим то, что уже работает • Дети сохраняют поля и методы родителя
Наследование #include <string> #include<iostream> class Movie//Базовый класс { protected: std::string title; int year; public: Movie(std::string newTitle, int newYear) : title(newTitle), year(newYear) { } int getYear() const{ return year; } std::string getTitle() const {return title; } void printInfo() { std::cout << "Movie " << title << "(" << year << ")" << std::endl; } }; int main() { Movie movie1("Senseless", 1998); movie1.printInfo(); return 0; }
Наследование class Serial : public Movie//Производный класс { int numSeries; public: Serial(std::string newTitle, int newYear, int nums) :Movie(newTitle, newYear), numSeries(nums) { } int getNumSeries() const{return numSeries;} void printInfo() { std::cout << "Serial " << title << "(" << year << ")" << numSeries << " episodes"<< std::endl; } }; int main() { Movie movie1("Senseless", 1998); movie1.printInfo(); Serial serial1("House M.D.", 2004, 135); serial1.printInfo(); return 0; }
Множественное наследование • У производного класса может быть несколько базовых class ColouredPoint : public Point, public ColouredItem { ... }; • Иерархия наследования class Person { … }; class Student: public Person { … }; class 2ndYearStudent: public Student { … }; Student - непосредственный базовый класс (direct base), а Person – косвенный базовый класс(indirect base) 2ndYearStudent
Наследование: уровни доступа class C { private: int a; protected: int b; public: int d; } class CPub: public C { недоступно доступно как protected доступно как public } class CPro: protected C { недоступно доступно как protected доступно как protected } class CPri: private C { недоступно доступно как private доступно как private }
Одноименные поля и методы • Используется поле производного класса • Доступ к полю базового – через спецификатор доступа :: class Point { public: int x; int y; } class RelativePoint: public Point { public: int x; int direction; int getAbsoluteX() { return Point::x + x; } }
Виртуальные функции class Circle : public Point protected: int r; public: Circle(int _x, int _y, int _r) : r(_r), Point(_x,_y) {}; void show() { // Вариант show для окружности } void hide() { // Вариант hide для окружности } void move(int new_x, int new_y) { hide(); x = new_x; y = new_y; show(); } }; class Point { public: int x,y; Point(int _x, int _y) : x(_x), y(_y) {}; void show() { // рисуем точку } void hide() { // стираем точку } void move(int new_x, new_y) { // перемещаем из (x,y) в (new_x, new_y) hide(); x=new_x; y=new_y; show(); } }; • Методы move одинаковы Circle c(10,10,5); Point p(20,20); c.move(50,50); //Circle::move p.move(70,70); //Point::move
Виртуальные функции class Circle : public Point protected: int r; public: Circle(int _x, int _y, int _r) : r(_r), Point(_x,_y) {}; void show() { // Вариант show для окружности } void hide() { // Вариант hide для окружности } }; class Point { public: int x,y; Point(int _x, int _y) : x(_x), y(_y) {}; virtualvoid show() { // рисуем точку } virtualvoid hide() { // стираем точку } void move(int new_x, new_y) { // перемещаем из (x,y) в (new_x, new_y) hide(); x=new_x; y=new_y; show(); } }; Circle c(10,10,5); Point p(20,20); c.move(50,50); //Point::move но с Circle::hide, Circle::show p.move(70,70); //Point::move
Виртуальные функции, полиморфизм • Указатель на производный класс может быть использован как указатель на базовый класс void moveElement(Point* pt, int delta_x, int delta_y) { pt->move(delta_x, delta_y); } int main() { Circle c; Point p; moveElement(&c); moveElement(&p); return 0; } • Полиморфизм - способность объекта вести себя по разному в зависимости от того, как им пользуются. • Использовать базовый класс вместо производного нельзя
Чисто виртуальные функции • Заранее известно, что метод базового класса вызываться не будет • Если есть хоть один виртуальный метод, нельзя создать экземпляр класса • Если нет полей, и все метод виртуальные – класс абстрактный class Figure { public: virtual double area()= 0; }; class Figure { public: virtual double area() { throw "error!"; } }; • class Square: public Figure • { • double length; • public: • Square(double l): length(l) { } • double area() { • return length * length; } • }; class Circle: public Figure { double radius; public: Circle(double r): radius(r) { } double area() { return 3.14159 * radius * radius; } };