SlideShare a Scribd company logo
Бублик Володимир Васильович Програмування - 2 Лекція 10. Ієрархічне програмування. Поліморфізм    Лекції для студентів 2 курсу
Challenges  ієрархій Різні реалізації одного й того ж класу ( StackAggregatingArray ,  StackDerivedFromArray ,  StackOnList) Розширення / спеціалізація класів ( DoubleList, CyclicList) Mixin  (підмішування) :  поєднання кількох функціональностей у одному класі ( PeekBack , Iterated)
Спеціалізація class  Parallelogram { protected : double   _ height; double   _ width; double   _ angle; public : Parallelogram ( double  h,  double  w,  double  a); double  area()  const ; double  height()  const ; double  width()  const ; double  angle()  const ; };
Спеціалізація Ромб і прямокутник служать прикладами   (спеціалізаціями )  паралелограма class  Rhombus:  public  Parallelogram { public : Rhombus ( double  h,  double  a) : Parallelogram (h, h, a){ }; };
Спеціалізація class  Rectangle:  public  Parallelogram { public : static const  double pi = 3.1415926535897932; Rectangle ( double  h,  double  w) : Parallelogram (h, w, pi/2){ }; double  area()  double { return  _height *  _ width; } };
Спеціалізація
Спеціалізація Як до прямокутника, так і ромба можна застосувати поведінку паралелограма Rhombus rh(10, pi/4); rh.area(); rh.height(); rh.width(); rh.angle(); Rectangle rec(10,20); // власна поведінка rec.area(); // успадкована поведінка Parallelogram :: rec.area(); rec.height(); rec.width(); rec.angle();
Управління доступом Можна закрити доступ до функції базового класу class  Rectangle:  public  Parallelogram { private : using   Parallelogram ::area(); public : static const  double pi = 3.1415926535897932; Rectangle ( double  h,  double  w) : Parallelogram (h, w, pi/2){ }; double  area()  double ; };
Mixin  (змішування) :  кратне успадкування Хижак class  Predator { private : string _name; string _favoritePray; public :  Predator (string name, pray); };
Mixin:  кратне успадкування Домашній улюбленець class  Pet { private : string _name; string _favoriteToy; public :  Pet (string name, string toy); };
Mixin:  кратне успадкування class  Cat:  public  Predator,  public  Pet { private : static unsigned int   _freeID; unsigned int  _myCatID; public :  Cat (string name, string toy, string prey): _myCatID (_freeID++), Predator (name, prey), Pet (name, toy){ }; };
Mixin:  кратне успадкування class  Cat:  public  Predator, p ublic  Pet
Consistency  (узгодженість) Хто слідкуватиме за узгодженістю імен в базових об'єктах? const string&  Predator :: rename (string newname) { return  name = newname; } void  cat::show()  const { cout<<Predator::name<<“ aka ”<<Pet::name; }
Спеціалізація  +  змішування: спільний базовий клас   Скільки паралелограмів міститься в одному квадраті? class  Square :  public  Rectangle,  public  Rhombus { public : Square ( double  side ) :  Rectangle( side, side ), Rhombus (side, pi/2) {}; };
Спільний базовий клас :  помилка
Неоднозначність   і неузгодженість Square sq(10); // Помилка: компілятор не знає, //  з якого паралелограма брати дані sq.width(); // Помилка: заміна атрибуту в одному з базових об'єктів // з наступним використанням іншого базового об'єкту sq.Rectangle::width() = 20; sq.Rectangle::height() = 20; cout<<sq.Rhombus::area();
Спільний базовий клас: запит
Віртуальне успадкування Відмінимо виклик конструктора в базових класах змішування Конструктор прямокутника (ромба) викличе конструктор паралелограма лише за умови, що його раніше не викликав конструктор квадрату class  Rectangle :  virtual   public  Parallelogram; class  Rhombus :  virtual   public  Parallelogram; class  Square :  public  Rectangle,  public  Rhombus;
Ініціалізація Parallelogram::Parallelogram( double  h,  double  w,  double  a): _height (h), _width (w), _angle (a) {}; Rectangle::Rectangle ( double  h,  double  w):  Parallelogram (h, w, pi/2) {}; Rhombus::Rhombus( double  side,  double  a ): Parallelogram (side, side, a) {}; Square::Square (  double  side ) :  Rectangle( side, side ), Rhombus (side,  pi/2 ) , Parallelogram( side, side, pi/2)   {};
Приклад // Спочатку паралелограм, потім прямокутник Rectangle rec(10, 20); // Спочатку паралелограм, потім ромб Rhombus rh(10, pi/3); // Конструктор паралелограма викликається // конструктором квадрата, прямокутник і ромб // використовують вже наявний паралелограм Square sq(10);
Контроль типів Простий обробник фігур void  processFigure ( const  Parallelogram & figure) { cout<<figure.whatAmI(); cout<<figure.area(); cout<<figure.perimeter(); return ; }
Доповнений паралелограм class  Parallelogram { protected : double   _ height,  _ width,  _ angle; public : Parallelogram ( double  h,  double  w,  double  a); double  area()  const ; const  string& whoAmI()  const { return  string(“Parallelogram”); } };
Доповнений ромб class  Rhombus:  public  Parallelogram { public : Rhombus ( double  h,  double  a) : Parallelogram (h, h, a){ }; const  string& whoAmI()  const { return  string(“Rhombus”); } }; Те ж саме для прямокутника і квадрата
Приклад   (маємо) // Очікуваний результат Parallelogram   par(20, 30, pi/6); processFigure (par); // паралелограм // Несподіваний результат Rhombus rh(10, pi/3); processFigure (rh); // паралелограм
Приклад (хочемо) // Очікуваний результат Parallelogram   par(20, 30, pi/6); processFigure (par); // паралелограм Rhombus rh(10, pi/3); processFigure (rh); // ромб
Повторення Статичний поліморфізм: Виклик функції за указником Simpson (a, b, eps, pf); Вибір функції за типами параметрі в Complex(1,2)+Complex(3,4); string(“First”)+string(“second”); (Динамічний) поліморфізм: вибрати функцію залежно від типу значення імені об'єкта figure.whatAmI();
Ієрархія типів Об'єкт може належати багатьом типам Квадрат одночасно є прямокутником, ромбом і паралелограмом Прямокутник і ромб одночасно є паралелограмами Ім'я паралелограма здатне приймати значення довільного допустимого типу Параметр  Parallelogram   & par  може прийняти паралелограм,   прямокутник, ромб або квадрат Указник  Parallelogram  *  ppar  може показувати на кожен з них, наприклад,   Parallelogram   * ppar = new Squre(10);
Віртуальні функції Об'єкти володіють даними-членами класу і розділяють функції-члени класу Прямий виклик класної функції (поки що) Triangle((0,0), (0,1), (1,0)).sideA(); Непрямий виклик  віртуальної  функції перевірити яке саме значення має  par взяти функцію (з таблиці віртуальних функцій  vtab ) Непрямий виклик поширюється лише на спеціально позначені функції
Доповнений паралелограм class  Parallelogram { protected : double   _ height,  _ width,  _ angle; public : Parallelogram ( double  h,  double  w,  double  a); virtual double  area()  const ;   virtual const  string& whoAmI()  const { return  string(“Parallelogram”); } };
Доповнений ромб class  Rhombus:  public  Parallelogram { public : Rhombus ( double  h,  double  a) : Parallelogram (h, h, a){ }; virtual const  string& whoAmI()  const { return  string(“Rhombus”); } }; Те ж саме для прямокутника і квадрата
Поліморфізм Можливість динамічно використовувати для роботи з похідними класами інтерфейс базового класу // Поліморфізм не використовується Rectangle rec(10, 20); rec.whoAmI(); // Поліморфізм Parallelogram * par = container.getParallelogram(); par->whoAmI();
Забутливе присвоєння Поліморфізм здатен проявитися лише при застосуванні указника базового класу або передачі базового класу відсилкою (в тому числі сталою) Присвоєння об'єкту похідного класу на місце, призначене для базового об'єкту, призведе до забування додаткових властивостей похідного типу і його зведення до базового Parallelogram par  =  Rectangle(10, 20);
Інтерфейс Можливість динамічно використовувати для роботи з похідними класами інтерфейс (неіснуючого)  абстрактного  базового класу class  Stack { public : virtual ~Stack () {} ; virtual   const  Elem& top() const =0; virtual   void  pop() =0; virtual   void  push( const   Elem &  value) =0; };
Абстрактний клас Відсутність реалізації класної функції позначається нулем Абстрактним називається клас, у якого відсутня реалізація хоча б однієї функції Використовуються для позначення спільного інтерфейсу класів, що допускають різні реалізації Об'єкт абстрактного класу створити не можна (чому?)
Успадкування інтерфейсу class  StackAggregatingArray: public  Stack { public : StackAggregatingArray ( size_t ); ~StackAggregatingArray (); const  Elem& top() const; void  pop() ; void  push( const   Elem &  value) ; private : static const  size_t  _ bos;  size_t _top; Array _array ; };
Успадкування інтерфейсу class  StackAggregatingArray: public  Stack { public : StackAggregatingArray ( size_t ); virtual  ~StackAggregatingArray (); virtual  const  Elem& top() const; virtual  void  pop() ; virtual  void  push( const   Elem &  value) ; private : static const  size_t  _ bos;  size_t _top; Array _stackArray ; };
Діаграма   реалізацій інтерфейсу
Зауваження Абстрактний клас повинен завжди мати (порожній) віртуальний деструктор Перевірте, що станеться, якщо Деструктор не матиме реалізації Деструктор не буде віртуальним
Виклик віртуальних функцій void  process(Stack & stack) { cout<<stack.top(); …………… }; StackDerivedFromArray sdfa; process(sdfa); StackAggregatingArray saga; process(saga);
Вправа Визначити і реалізувати абстрактний клас (інтерфейс) трикутника
З'єднання інтерфейсів class  PeekBack { public : virtual bool  peekback( size_t  i, Elem& elem) c onst =0; virtual  ~PeekBack() { }; }; class  PeekbackStack:  virtual public  Stack,  public  PeekBack { public : virtual bool  peekback(size_t i, Elem& elem)  const =0; virtual  ~PeekbackStack() { }; };
Реалізація з'єднаного інтерфейсу class  Peek B ackStackAgregating Array : // Успадкування інтерфейсу підглядань public  PeekbackStack, // Реалізація інтерфейсу стеку public  StackAgregatingArray, { public : // Реалізації інтерфейсу підглядань Peek B ackStackAgregating Array  ( size_t  size) ;  virtual  ~AgregatingPeekbackStack() ; virtual bool  peekback(int i, Elem& elem)  const ; };
Висновки Віртуальні функції служать для Реалізації інтерфейсів Заміщення ( overriding )  реалізації функції базового класу реалізацією, призначеною для підкласу Поліморфізм приводить до того, що одне і те ж ім'я (указник) протягом виконання програми набуває значень в різних класах, але із спільним інтерфейсом Порівняйте з довизначенням ( overloading )

More Related Content

PPT
09 Static Polymorphism
PDF
Mka python jr-urok_03_ua_1563258828
PPT
06 Pointers To Class Members
PPT
Programuvanna na movi_pascal
PDF
Coding for Future in Lutsk. JavaScript. Part 8
PDF
Coding for Future in Lutsk. JavaScript. Part 6
PDF
Coding for Future in Lutsk. JavaScript. Part 9
PPT
05 Operations And Utilities
09 Static Polymorphism
Mka python jr-urok_03_ua_1563258828
06 Pointers To Class Members
Programuvanna na movi_pascal
Coding for Future in Lutsk. JavaScript. Part 8
Coding for Future in Lutsk. JavaScript. Part 6
Coding for Future in Lutsk. JavaScript. Part 9
05 Operations And Utilities

Viewers also liked (16)

PPT
07 Localisation
PPT
04 Operators
PPT
08 Templates
PPT
03 Right Of Access
PPT
11 Iterated Containers
PPT
03 Constants And Variables
PPT
05 Arrays
PPT
02 Copying Objects
PPT
Seo for Wordpress - Wordcamp Montreal 2012
PPT
Corporate Social Media Strategy
PPSX
Social Media Marketing 101
PPT
WP-MU 101: How to Install and Avoid Common Mistakes
PPT
Social Media & Personal Branding for Career Advancement
PPT
02 Arithmetic Data Types
PPT
Podcamp montreal 2010 search & social
PPT
Syncing SEO & Content Strategies
07 Localisation
04 Operators
08 Templates
03 Right Of Access
11 Iterated Containers
03 Constants And Variables
05 Arrays
02 Copying Objects
Seo for Wordpress - Wordcamp Montreal 2012
Corporate Social Media Strategy
Social Media Marketing 101
WP-MU 101: How to Install and Avoid Common Mistakes
Social Media & Personal Branding for Career Advancement
02 Arithmetic Data Types
Podcamp montreal 2010 search & social
Syncing SEO & Content Strategies
Ad

Similar to 10 Polymorphism (20)

PPT
01 Incapsulation
PPT
07 Containers
PPT
General Functors
PPT
General Functors ...
PPT
09 Object And Class Hierarchy
PPTX
IT Talks The c++'s simplest smart pointers in depth
PPT
08 Functions
PPT
04 Object Hierarchy
PPT
Oop - TTm
PPT
06 Data Structures
PPTX
тема 7
PDF
[Knowledge Sharing] - Behavioral patterns by Pavlo Serdyuk (UKR)
PPTX
PDF
C++ Basics
PPT
UML Prezentation class diagram
PPT
Название презентации
PPT
Prezentation class diagram
01 Incapsulation
07 Containers
General Functors
General Functors ...
09 Object And Class Hierarchy
IT Talks The c++'s simplest smart pointers in depth
08 Functions
04 Object Hierarchy
Oop - TTm
06 Data Structures
тема 7
[Knowledge Sharing] - Behavioral patterns by Pavlo Serdyuk (UKR)
C++ Basics
UML Prezentation class diagram
Название презентации
Prezentation class diagram
Ad

10 Polymorphism

  • 1. Бублик Володимир Васильович Програмування - 2 Лекція 10. Ієрархічне програмування. Поліморфізм Лекції для студентів 2 курсу
  • 2. Challenges ієрархій Різні реалізації одного й того ж класу ( StackAggregatingArray , StackDerivedFromArray , StackOnList) Розширення / спеціалізація класів ( DoubleList, CyclicList) Mixin (підмішування) : поєднання кількох функціональностей у одному класі ( PeekBack , Iterated)
  • 3. Спеціалізація class Parallelogram { protected : double _ height; double _ width; double _ angle; public : Parallelogram ( double h, double w, double a); double area() const ; double height() const ; double width() const ; double angle() const ; };
  • 4. Спеціалізація Ромб і прямокутник служать прикладами (спеціалізаціями ) паралелограма class Rhombus: public Parallelogram { public : Rhombus ( double h, double a) : Parallelogram (h, h, a){ }; };
  • 5. Спеціалізація class Rectangle: public Parallelogram { public : static const double pi = 3.1415926535897932; Rectangle ( double h, double w) : Parallelogram (h, w, pi/2){ }; double area() double { return _height * _ width; } };
  • 7. Спеціалізація Як до прямокутника, так і ромба можна застосувати поведінку паралелограма Rhombus rh(10, pi/4); rh.area(); rh.height(); rh.width(); rh.angle(); Rectangle rec(10,20); // власна поведінка rec.area(); // успадкована поведінка Parallelogram :: rec.area(); rec.height(); rec.width(); rec.angle();
  • 8. Управління доступом Можна закрити доступ до функції базового класу class Rectangle: public Parallelogram { private : using Parallelogram ::area(); public : static const double pi = 3.1415926535897932; Rectangle ( double h, double w) : Parallelogram (h, w, pi/2){ }; double area() double ; };
  • 9. Mixin (змішування) : кратне успадкування Хижак class Predator { private : string _name; string _favoritePray; public : Predator (string name, pray); };
  • 10. Mixin: кратне успадкування Домашній улюбленець class Pet { private : string _name; string _favoriteToy; public : Pet (string name, string toy); };
  • 11. Mixin: кратне успадкування class Cat: public Predator, public Pet { private : static unsigned int _freeID; unsigned int _myCatID; public : Cat (string name, string toy, string prey): _myCatID (_freeID++), Predator (name, prey), Pet (name, toy){ }; };
  • 12. Mixin: кратне успадкування class Cat: public Predator, p ublic Pet
  • 13. Consistency (узгодженість) Хто слідкуватиме за узгодженістю імен в базових об'єктах? const string& Predator :: rename (string newname) { return name = newname; } void cat::show() const { cout<<Predator::name<<“ aka ”<<Pet::name; }
  • 14. Спеціалізація + змішування: спільний базовий клас Скільки паралелограмів міститься в одному квадраті? class Square : public Rectangle, public Rhombus { public : Square ( double side ) : Rectangle( side, side ), Rhombus (side, pi/2) {}; };
  • 16. Неоднозначність і неузгодженість Square sq(10); // Помилка: компілятор не знає, // з якого паралелограма брати дані sq.width(); // Помилка: заміна атрибуту в одному з базових об'єктів // з наступним використанням іншого базового об'єкту sq.Rectangle::width() = 20; sq.Rectangle::height() = 20; cout<<sq.Rhombus::area();
  • 18. Віртуальне успадкування Відмінимо виклик конструктора в базових класах змішування Конструктор прямокутника (ромба) викличе конструктор паралелограма лише за умови, що його раніше не викликав конструктор квадрату class Rectangle : virtual public Parallelogram; class Rhombus : virtual public Parallelogram; class Square : public Rectangle, public Rhombus;
  • 19. Ініціалізація Parallelogram::Parallelogram( double h, double w, double a): _height (h), _width (w), _angle (a) {}; Rectangle::Rectangle ( double h, double w): Parallelogram (h, w, pi/2) {}; Rhombus::Rhombus( double side, double a ): Parallelogram (side, side, a) {}; Square::Square ( double side ) : Rectangle( side, side ), Rhombus (side, pi/2 ) , Parallelogram( side, side, pi/2) {};
  • 20. Приклад // Спочатку паралелограм, потім прямокутник Rectangle rec(10, 20); // Спочатку паралелограм, потім ромб Rhombus rh(10, pi/3); // Конструктор паралелограма викликається // конструктором квадрата, прямокутник і ромб // використовують вже наявний паралелограм Square sq(10);
  • 21. Контроль типів Простий обробник фігур void processFigure ( const Parallelogram & figure) { cout<<figure.whatAmI(); cout<<figure.area(); cout<<figure.perimeter(); return ; }
  • 22. Доповнений паралелограм class Parallelogram { protected : double _ height, _ width, _ angle; public : Parallelogram ( double h, double w, double a); double area() const ; const string& whoAmI() const { return string(“Parallelogram”); } };
  • 23. Доповнений ромб class Rhombus: public Parallelogram { public : Rhombus ( double h, double a) : Parallelogram (h, h, a){ }; const string& whoAmI() const { return string(“Rhombus”); } }; Те ж саме для прямокутника і квадрата
  • 24. Приклад (маємо) // Очікуваний результат Parallelogram par(20, 30, pi/6); processFigure (par); // паралелограм // Несподіваний результат Rhombus rh(10, pi/3); processFigure (rh); // паралелограм
  • 25. Приклад (хочемо) // Очікуваний результат Parallelogram par(20, 30, pi/6); processFigure (par); // паралелограм Rhombus rh(10, pi/3); processFigure (rh); // ромб
  • 26. Повторення Статичний поліморфізм: Виклик функції за указником Simpson (a, b, eps, pf); Вибір функції за типами параметрі в Complex(1,2)+Complex(3,4); string(“First”)+string(“second”); (Динамічний) поліморфізм: вибрати функцію залежно від типу значення імені об'єкта figure.whatAmI();
  • 27. Ієрархія типів Об'єкт може належати багатьом типам Квадрат одночасно є прямокутником, ромбом і паралелограмом Прямокутник і ромб одночасно є паралелограмами Ім'я паралелограма здатне приймати значення довільного допустимого типу Параметр Parallelogram & par може прийняти паралелограм, прямокутник, ромб або квадрат Указник Parallelogram * ppar може показувати на кожен з них, наприклад, Parallelogram * ppar = new Squre(10);
  • 28. Віртуальні функції Об'єкти володіють даними-членами класу і розділяють функції-члени класу Прямий виклик класної функції (поки що) Triangle((0,0), (0,1), (1,0)).sideA(); Непрямий виклик віртуальної функції перевірити яке саме значення має par взяти функцію (з таблиці віртуальних функцій vtab ) Непрямий виклик поширюється лише на спеціально позначені функції
  • 29. Доповнений паралелограм class Parallelogram { protected : double _ height, _ width, _ angle; public : Parallelogram ( double h, double w, double a); virtual double area() const ; virtual const string& whoAmI() const { return string(“Parallelogram”); } };
  • 30. Доповнений ромб class Rhombus: public Parallelogram { public : Rhombus ( double h, double a) : Parallelogram (h, h, a){ }; virtual const string& whoAmI() const { return string(“Rhombus”); } }; Те ж саме для прямокутника і квадрата
  • 31. Поліморфізм Можливість динамічно використовувати для роботи з похідними класами інтерфейс базового класу // Поліморфізм не використовується Rectangle rec(10, 20); rec.whoAmI(); // Поліморфізм Parallelogram * par = container.getParallelogram(); par->whoAmI();
  • 32. Забутливе присвоєння Поліморфізм здатен проявитися лише при застосуванні указника базового класу або передачі базового класу відсилкою (в тому числі сталою) Присвоєння об'єкту похідного класу на місце, призначене для базового об'єкту, призведе до забування додаткових властивостей похідного типу і його зведення до базового Parallelogram par = Rectangle(10, 20);
  • 33. Інтерфейс Можливість динамічно використовувати для роботи з похідними класами інтерфейс (неіснуючого) абстрактного базового класу class Stack { public : virtual ~Stack () {} ; virtual const Elem& top() const =0; virtual void pop() =0; virtual void push( const Elem & value) =0; };
  • 34. Абстрактний клас Відсутність реалізації класної функції позначається нулем Абстрактним називається клас, у якого відсутня реалізація хоча б однієї функції Використовуються для позначення спільного інтерфейсу класів, що допускають різні реалізації Об'єкт абстрактного класу створити не можна (чому?)
  • 35. Успадкування інтерфейсу class StackAggregatingArray: public Stack { public : StackAggregatingArray ( size_t ); ~StackAggregatingArray (); const Elem& top() const; void pop() ; void push( const Elem & value) ; private : static const size_t _ bos; size_t _top; Array _array ; };
  • 36. Успадкування інтерфейсу class StackAggregatingArray: public Stack { public : StackAggregatingArray ( size_t ); virtual ~StackAggregatingArray (); virtual const Elem& top() const; virtual void pop() ; virtual void push( const Elem & value) ; private : static const size_t _ bos; size_t _top; Array _stackArray ; };
  • 37. Діаграма реалізацій інтерфейсу
  • 38. Зауваження Абстрактний клас повинен завжди мати (порожній) віртуальний деструктор Перевірте, що станеться, якщо Деструктор не матиме реалізації Деструктор не буде віртуальним
  • 39. Виклик віртуальних функцій void process(Stack & stack) { cout<<stack.top(); …………… }; StackDerivedFromArray sdfa; process(sdfa); StackAggregatingArray saga; process(saga);
  • 40. Вправа Визначити і реалізувати абстрактний клас (інтерфейс) трикутника
  • 41. З'єднання інтерфейсів class PeekBack { public : virtual bool peekback( size_t i, Elem& elem) c onst =0; virtual ~PeekBack() { }; }; class PeekbackStack: virtual public Stack, public PeekBack { public : virtual bool peekback(size_t i, Elem& elem) const =0; virtual ~PeekbackStack() { }; };
  • 42. Реалізація з'єднаного інтерфейсу class Peek B ackStackAgregating Array : // Успадкування інтерфейсу підглядань public PeekbackStack, // Реалізація інтерфейсу стеку public StackAgregatingArray, { public : // Реалізації інтерфейсу підглядань Peek B ackStackAgregating Array ( size_t size) ; virtual ~AgregatingPeekbackStack() ; virtual bool peekback(int i, Elem& elem) const ; };
  • 43. Висновки Віртуальні функції служать для Реалізації інтерфейсів Заміщення ( overriding ) реалізації функції базового класу реалізацією, призначеною для підкласу Поліморфізм приводить до того, що одне і те ж ім'я (указник) протягом виконання програми набуває значень в різних класах, але із спільним інтерфейсом Порівняйте з довизначенням ( overloading )