虚拟功能覆盖范围是否违反LSP?

时间:2019-05-03 15:40:49

标签: c++ design-patterns liskov-substitution-principle

我正在学习设计模式,但是我认为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 个答案:

答案 0 :(得分:1)

LSP要求子类必须遵守其超类的合同。

这意味着您提到了有关参数和返回类型的4条规则,但是合同也可以 包含很多未在代码中捕获的东西(尽管如果被捕获则会很不错)在评论中!)。

没有其他要求,因此除非Animal的合同中有一条规定必须只吃普通食品的规则,否则您可以优先使用。如果存在这样的规则,则不应将eat方法设为虚拟。