Не нарушает ли виртуальная функция покрытия LSP? - PullRequest
0 голосов
/ 03 мая 2019

Я изучаю шаблоны проектирования, но я думаю, что переписывание виртуальных функций C ++ нарушает LSP.

  1. Подклассы могут реализовывать абстрактные методы родительского класса, но они не могут переопределять неабстрактныйметоды родительского класса.

  2. Подклассы могут добавлять свои собственные уникальные методы.

  3. Когда подкласс переопределяет или реализует методы родительского класса,Предварительные условия метода (то есть формальные параметры метода) более мягкие, чем входные параметры родительского класса.

  4. Когда метод подкласса реализует абстрактный метод родительского класса, постусловиеМетод (то есть возвращаемое значение метода) является более строгим, чем родительский класс.

Но для достижения полиморфизма мне нужно переписать (переопределить).Неужели я не так понимаю?

class Animal;
class Cat;

void fun(Animal *xyz) { xyz->eat(); }

class Animal
{
 public:
    virtual void eat() { ::std::cout << "I'm eating generic food."; }
};

class Cat : public Animal
{
  public:
    // override.
    // Whether it violates the principle?
    void eat() { ::std::cout << "I'm eating a rat."; }
};

1 Ответ

1 голос
/ 03 мая 2019

LSP требует, чтобы подкласс поддерживал контракт своего суперкласса.

Это подразумевает 4 правила, которые вы упоминаете о параметрах и типах возвращаемых данных, но контракт может также включать много вещейэто не фиксируется в коде (хотя было бы неплохо, если бы оно было зафиксировано в комментариях!).

Других требований нет, поэтому, если в контракте Animal нет правила, в котором это указанодолжны есть только общую пищу, тогда ваше переопределение в порядке.Если является таким правилом, то не стоит делать метод eat виртуальным.

...