Страницы

Поиск по вопросам

вторник, 13 ноября 2018 г.

Поведенческий полиморфизм подтипов

Цитата из википедии: Наследование, — даже в языках программирования, которые поддерживают применение наследования как механизма, обеспечивающего полиморфизм подтипов, — не гарантирует поведенческий полиморфизм подтипов; смотри: «Принцип подстановки» Барбары Лисков.
Что же здесь подразумевают под поведенческим полиморфизмом подтипов? Как грамотно и лаконично ответить на этот вопрос?
Я же понимаю это так: Опять же цитата из википедии: Более простыми словами можно сказать, что поведение наследуемых классов не должно противоречить поведению, заданному базовым классом, то есть поведение наследуемых классов должно быть ожидаемым для кода, использующего переменную базового типа. Из этого следует, что наследование не защищает программиста, от того, что он может изменить поведение в переопределенном методе. Например метод add() в базовом классе добавляет объект, а его можно легко переопределить и этот метод станет удалять некий объект. Сохранение поведения базового метода и есть поведенческий полиморфизм.
Прав ли я?


Ответ

Вы все верно понимаете. Поведенческий полиморфизм это когда дочерний класс не меняет поведения родительского. Например представьте ситуацию, у нас есть класс
class Rechtangle { protected int width; protected int height;
public void setWidth(int w) { this.width = w; }
public void setHeight(int h) { this.height = h; }
public int area() { return width * height; } }
И мы добавляем новый класс "Квадрат", чем он отличается от прямоугольника, тем что его стороны должны изменяться одновременно, если мы меняем высоту, то и должна меняться ширина, пример
class Square extends Rechtangle { @Override public void setWidth(int w) { this.width = w; this.height = w; }
@Override public void setHeight(int h) { this.width = h; this.height = h; } }
А теперь представьте, что какой-то программист написал следующий код
void mainProcedure(Rechtangle figure) { figure.setWidth(5); figure.setHeight(3);
assert figure.area() == 15; }
Давайте теперь вызовем эту функцию с реализацией квадрата
mainProcedure(new Square())
Будет выброшено AssertionError, вот вам наглядное нарушение принципа LSP и поведенческого полиморфизма. Потому что фактически квадрат это не прямоугольник и разработчик процедуры mainProcedure не ожидал что он может получить квадрат маскирующийся за прямоугольником. Программист который написал процедуру прав. Он проверил контракт который должен был соблюдаться прямоугольником, но был нарушен квадратом.

Комментариев нет:

Отправить комментарий