1 / 35

Наследование

Наследование. Композиция. class Circle { Point m_center ; double m_radius ; public : double GetSquare () const ; };. - отношение «класс А содержит класс Б». Разрабатываем второй класс:. class ColoredCircle { Point m_center ; double m_radius ; Color m_color ; public :

kalkin
Download Presentation

Наследование

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Наследование

  2. Композиция • classCircle • { • Pointm_center; • doublem_radius; • public: • doubleGetSquare() const; • }; -отношение «класс А содержит класс Б»

  3. Разрабатываем второй класс: • classColoredCircle • { • Pointm_center; • doublem_radius; • Colorm_color; • public: • doubleGetSquare() const; • voidSetColor(Colorcolor); • };

  4. classColoredCircle • { • Pointm_center; • doublem_radius; • Colorm_color; • public: • doubleGetSquare() const; • voidSetColor(Colorcolor); • }; • classCircle • { • Pointm_center; • doublem_radius; • public: • doubleGetSquare() const; • };

  5. Wrapper(паттерн, который здесь не подходит) • classColoredCircle • { • Circlem_circle; • Color m_color; • public: • double GetSquare() const • { • returnm_circle.GetSquare(); • } • };

  6. Наследование (оптимальное решение) • classColoredCircle : publicCircle • { • Colorm_color; • public: • voidSetColor(Color color); • }; ColoredCircle cc; cc.SetColor(green); var square = cc.GetSquare();

  7. Наследование - отношение «класс А является классом Б» (IS-A) Иерархия классов 1. Велосипед является (is a) транспортным средством? 2. Транспортное средство является велосипедом?

  8. Наследование – создание новых классов из уже существующих, путем • заимствования их данных и методов. • Как правило, производный класс является частным случаем • базового класса. Transport Aircraft сlassимя_класса: спецификатор_доступаимя_базового_класса { };

  9. 1. Наследование– создание нового класса на основе существующего. • 2. Содержимое базовогокласса заимствуется производным классом. • 3. Наследование позволяет использовать уже написанный код базового класса: • - дополняя его новыми полями данных • - дополняя его новыми методами • - переопределяя существующие методы • Достоинства наследования: • Позволяет изменять поведение классов с закрытым кодом. • Уменьшение дублирования кода. • Упрощается модификация программы. • Структура программы становится более лаконичной. • Недостатки наследования: • Сильная связность (проблема «хрупких базовых классов»).

  10. Композиция vs. Наследование Label  ColoredLabel Point  Circle Car  Driver File  MP3File Man  Student Композиция – «содержит» Наследование – «является частным случаем» В иерархии 1:1 нужно лишь правильно сделать выбор между композицией и наследованием (прибегая ко второму лишь при необходимости).

  11. Конструкторы и наследование Первым всегда вызывается конструктор базового класса! Варианты вызова: 1. Неявный (автоматический) вызов – вызывается конструктор по умолчанию базового класса. 2. Явный вызов – в конструкторе производного класса через название класса- предка(можно передать параметры).

  12. Порядок вызова конструкторов: • Конструкторы базового класса (в порядке объявления при наследовании). • Конструкторы объектов-элементов производного класса (в порядке объявления в теле класса). • Конструктор производного класса

  13. class Window • { • intwidth; • intheight; • public: • Window() : width(0), height(0) • { • } • }; • class Button : public Window • { • std::string text; • public: • Button(std::string text) • { • this->text = text; • } • };

  14. Window* wnd = new Window(); Button* btn = new Button("OK");

  15. Явный вызов конструктора базового класса class Text { std::string text; public: Text(std::string text) : text(text) { } }; classColoredText : public Text { Colorcolor; public: ColoredText(std::string text, Color color) : Text(text), color(color) { } };

  16. Пример наследования с дополнением • classButton • { • intm_left; • intm_top; • intm_width; • intm_height; • std::stringm_caption; • public: • Button(); • intGetWidth() const; • }; • classPictureButton: publicButton • { • Image m_icon; • public: • PictureButton(); • };

  17. Пример наследования с ограничением • class Matrix • { • protected: • float** m; • introws; • intcols; • public: • Matrix(int rows, int cols) • { • } • }; • classSquareMatrix: public Matrix • { • public: • SquareMatrix (intsize) : Matrix(size, size) • { • } • float CalcDet(); • };

  18. Пример наследования: общий предок • classCar • { • std::stringm_model; • float m_velocity; • public: • voidAccelerate(floataccel); • }; • classAvia • { • std::stringm_model; • float m_velocity; • float m_altitude; • public: • voidVerticalAccelerate(floataccel); • };

  19. classTransport • { • std::stringm_model; • floatm_velocity; • }; • classCar : publicTransport • { • public: • voidHandBrakeOn(); • }; • classAvia : publicTransport • { • floatm_altitude; • public: • voidVerticalAccelerate(floataccel); • };

  20. Классификация наследования (по ТимотиБадду): • 1. Специализация (наследник является специализированной формой предка). • 2. Спецификация (дочерний класс реализует поведение, описанное в предке). • 3. Конструирование или Варьирование (наследник использует методы предка, • но не является его подтипом). • 4. Расширение (в потомок добавляют новые методы, расширяя поведение предка). • 5. Обобщение (потомок обобщает поведение предка). • 6. Ограничение (потомок ограничивает поведение предка).

  21. Наследование и спецификаторы доступа • Открытые элементы класса доступны всем. • Закрытые элементы класса доступны только его методам и друзьям класса. • Защищенные элементы базового класса доступны методам и друзьям базового • класса, а также методам и друзьям производного класса. • Методы производного класса могут обращаться к открытым и защищенным • элементам базового класса.

  22. Контракт Принцип замещения Лисков: производные классы полностью поддерживают контракт базового (вместо объекта базового класса везде можно подставить объект производного). Открытое наследование – наследование интерфейса. Закрытое наследование – наследование реализации.

  23. Замещающая функция • class Man • { • std::string name; • public: • std::string ToString() • { • return name; • } • };

  24. #include<sstream> • class Student : public Man • { • intgroup; • public: • std::string ToString() • { • std::stringstreamss; • ss<< Man::ToString() • << ", " • << group; • returnss.str(); • } • };

  25. Множественное наследование • classIstream • { • std::string read(); • } • classOstream • { • void write(std::string str); • } • classIOstream : publicIstream, publicOstream • { • } Возможен конфликт имен

  26. class Foo • { • public: • Foo(): a(b), b(c), c(0){} • private: • inta; • intb; • intc; • };

  27. class A { public: A() {} }; class B { public: B() {} }; class C : public A, public B { public: C(): B(), A() {} };

  28. Конфликт имен и его разрешение • class A • { • public: • std::string GetTypeName() { return "A"; } • }; • class B • { • public: • std::string GetTypeName() { return "B"; } • }; • class C: public A, public B • { • }; C c; std::cout << c.GetTypeName();//?

  29. Виртуальное наследование class A { public: void f(){} }; class B : virtual public A { }; class C : virtual public A { }; class D : public B, public C { };

  30. Приведения типов intwidth = 1024; intheight = 768; floatasp = float(width) / height; floatpi= 3.14; intp= static_cast<int>(pi);

  31. float f = 1.0f; int* n = static_cast<int*>(&f); int* n = reinterpret_cast<int*>(&f); // Ошибка компиляции int i = 0; constint* pI = &i; int* j = const_cast<int*> (pI);

  32. Понижающее приведение class Base { }; class Child : public Base { }; void main() { Base* pBase = new Child(); Child* pChild = static_cast<Child*>(pBase); }

  33. class Alien { }; Base* pBase = (Base*)new Alien(); Child* pChild = static_cast<Child*>(pBase); //?

  34. class Base • { • virtual void f(){} • }; • class Alien • { • virtual void ff(){} • }; • void main() • { • Base* pBase = (Base*)new Alien(); • Child* pChild = dynamic_cast<Child*>(pBase); • if (pChild){ • } • }

More Related