• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
OO Design with C++: 1. Inheritance, part 1
 

OO Design with C++: 1. Inheritance, part 1

on

  • 1,131 views

 

Statistics

Views

Total Views
1,131
Views on SlideShare
1,131
Embed Views
0

Actions

Likes
1
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Public vs. protected interface - two types of clients {part. Meyers1.41}. Containment as "has-a" or "is-implemented-via" relationship {Meyers1.40} Private inheritance - reasons of use instead of containment {Meyers1.42}

OO Design with C++: 1. Inheritance, part 1 OO Design with C++: 1. Inheritance, part 1 Presentation Transcript

  • C++ : наследование, часть 1 Дмитрий Штилерман, Рексофт
  • Краткое содержание первой части
    • Открытое наследование (public inheritance) как отношение "is-a” .
    • Иерархическая и другие виды классификаций.
    • Отношение “is-a” - возможные ошибки проектирования и способы их предотвращения.
    • Наследование интерфейса и наследование реализации.
    • Применение виртуальных методов.
  • Открытое наследование (public inheritance) - отношение "is-a" class Person {}; class Student : public Person {}; class Teacher : public Person {}; void f(Person&) {…} void g() { Student s; Teacher t; f(s); f(t); } Отношение “is-a” организует объекты в виде иерархической классификации.
  • Виды классификаций
    • А какие бывают классификации?
    • Иерархическая
    • Комбинативная
    • Параметрическая
    • Смешанные (на разных уровнях - разные виды)
    • А.А.Любищев, «О форме естественной системы организмов»
  • Виды классификаций - иерархическая
    • К лассы находятся в отношении “надкласс-подкласс”.
    • Каждый класс имеет характерные признаки, присущие только ему из всех его «братьев».
    • Пример: систематика живых организмов.
    • Выбор признаков определяет стратегию классификации.
    • Примеры стратегий:
      • Филогенетическая (общность определяется происхождением).
      • Морфологическая (общность определяется формой).
    Млекопитающие Выкармливают детенышей молоком Приматы Всеядные, зубная система гетеродонтная, глаза направлены вперед Высшие обезьяны Нет хвоста
  • Виды классификаций - комбинативная
    • Принадлежность к классу определяется значения ми некоторых признаков.
    • Признаки могут сочетаться произвольным образом .
    • Пример: матрица Boston Consulting Group для оценки компаний .
    Высокие темпы роста Знаки вопроса Звезды Дойные коровы Собаки Низ кие темпы роста Большая доля рынка Малая доля рынка ???
  • Виды классификаций - параметрическая
    • Принадлежность к классу определяется значениями немногих существенных параметров.
    • Большинство характеристик объекта коррелирует с существенными параметрами.
    • Пример: периодическая система элементов (существенный параметр - атомный вес) .
  • Отношение “is-a” - как можно ошибиться? (1) class StupidBird {public: virtual void fly() = 0;}; class StupidEagle : public StupidBird {public: virtual void fly();}; class StupidPenguin : public StupidBird {public: virtual void fly();}; Пингвины не умеют летать. Как мы собираемся реализовывать Stupid Penguin::fly()?
  • Отношение “is-a” - как можно ошибиться? (2) class Rectangle { public: int getHeight() const; virtual void setHeight(int); int getWidth() const; virtual void setWidth(int); }; void RectangleTest(Rectangle& r) { r.setHeight(4); r.setWidth(5); int S = r.getHeight()*r.getWidth(); assert(S==20); } class Square : public Rectangle { public: void setHeight(int h) { Rectangle::setHeight(h); Rectangle::setWidth(h); } void setWidth(int w) { Rectangle::setWidth(w); Rectangle::setHeight(w); } };
  • Отношение “is-a” - как не ошибиться?
    • Важно поведение объекта, а не классификация, действующая в предметной области.
    • Все, верное для базового класса, должно быть верным и для производного.
    • Интерфейс класса должен быть полным и минимальным.
  • Отношение “is-a” - The Liskov Substitution Principle
    • If for each object o 1 of type S there is an object o 2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o 1 is substituted for o 2 then S is a subtype of T.
    • Barbara Liskov, “Data Abstraction & Hierarchy”
    • An object-oriented function that uses pointers or references to a base class must be able to use objects of derived classes without knowing it.
    • Robert C. Martin, “The Liskov Substitution Principle”
  • Отношение “is-a” - как исправить ошибку? (1) В рамках задачи неверно утверждение «все птицы умеют летать». Значит, неправильно делать fly() методом Bird. Решение из обычного орнитологического определителя: дополнительная теза-антитеза «летает - не летает».
  • Отношение “is-a” - как исправить ошибку? (2) class Rectangular { public: virtual int getHeight() const = 0; virtual int getWidth() const = 0; }; class Square : public Rectangular { public: virtual int getHeight() const; virtual int getWidth() const; void setSide(int s); }; class Rectangle : public Rectangular { public: virtual int getHeight() const; virtual int getWidth() const; void setHeight(int h); void setWidth(int w); };
  • Наследование интерфейса и наследование реализации
    • При проектировании базовых и производных классов важно различать наследование интерфейса и реализации.
    • Можно наследовать то и другое как по отдельности, так и вместе.
    • Конкретная семантика наследования естественно определяется типом метода. Метод м.б. чисто виртуальный, виртуальный, невиртуальный.
  • Наследование интерфейса class Shape {public: virtual void draw() = 0;}; class Circle : public Shape {public: virtual void draw();}; class Rectangle : public Shape {public: virtual void draw();};
    • Каждая фигура должна уметь себя нарисовать, следовательно метод draw() должен входить в интерфейс Shape .
    • Невозможно нарисовать «фигуру вообще», следовательно Shape::draw() не может иметь реализации.
    • Pure virtual function
  • Наследование интерфейса и обязательной реализации class Shape { public: virtual void draw() = 0; virtual void erase() = 0; bool getVisible() const {return m_bVisible;} void setVisible(bool bVisible) { m_bVisible = bVisible; if(m_bVisible) draw(); else erase(); } private: bool m_bVisible; };
    • Каждую фигуру можно показать или спрятать, используя метод setVisible() .
    • Протокол, по которому работает метод setVisible() , должен быть одним и тем же для всех производных классов.
    • Non-virtual function
    • See also: Template Method pattern
  • Наследование интерфейса и реализации по умолчанию (1) class Shape { public: virtual void draw() = 0; virtual void erase() = 0; virtual void redraw() { /* Простейший способ/ erase(); draw(); } }; class Sprite : public Shape { public: virtual void redraw() {/* Оптимизированный способ*/} };
    • Изображение каждой фигуры можно обновить, используя метод redraw() .
    • Существует простейший всегда работающий способ перерисовки.
    • Для конкретных производных классов может существовать лучший (например, более быстрый) способ перерисовки.
    • Virtual function
  • Наследование интерфейса и реализации по умолчанию (2) class Shape { public: virtual void redraw() = 0; protected: void default_redraw() {erase(); draw();} }; class Rectangle : public Shape { public: virtual void redraw() {default_redraw();} }; class Sprite : public Shape { public: virtual void redraw() {/*Оптимизированный способ*/} };
    • Изображение каждой фигуры можно обновить, используя метод redraw() .
    • Существует способ перерисовки, работающий часто, но не всегда .
    • Каждый производный класс обязан реализовать redraw() , возможно используя реализацию по умолчанию.
    • Pure virtual function & Protected non-virtual function
  • Продолжение в следующей серии
    • Public & protected interface .
    • Случаи видимости наследования ( public, protected, private) и их семантика.
    • О тношения “has-a” и “is-implemented-by”.
    • Композиция (aggregation).
    • Делегирование ( delegation) .
    • Изоляция ( insulation ).