c++ - 虚函数覆盖是否违反 LSP?
问题描述
我正在学习设计模式,但我认为 C++ 虚函数重写违反了 LSP。
子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
子类可以添加自己独特的方法。
当子类重写或实现父类的方法时,方法的前置条件(即方法的形参)比父类的输入参数更宽松。
当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)比父类更严格。
但是为了实现多态性,我必须重写(覆盖)。难道是我理解错了?
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."; }
};
解决方案
LSP 要求子类必须遵守其超类的合同。
这意味着您提到的关于参数和返回类型的 4 条规则,但是合同还可以包含许多代码中未捕获的内容(尽管如果在注释中捕获它会很好!)。
没有其他要求,所以除非Animal
's 合同中有规定必须只吃普通食品,否则您的替代是可以的。如果有这样的规则,那么您不应该将eat
方法设为虚拟。
推荐阅读
- matlab - 代理何时在 Matalb 强化学习工具箱中学习?
- mysql - 如何进行项目平衡
- html - 当文本区域位于网格容器中时如何使 cols="" 工作
- python-3.x - 插入语句返回绑定参数需要值
- javascript - 通过 react-router 处理带有斜线的路径的方法是什么?
- nginx - nginx Http2 Push 在 Vary 时失败:接受标头集
- javascript - 带有 moment.js 的日期格式“D-#”或“D+#”
- c# - 如何选择具有相同类名的html元素?
- matlab - 颜色从暗到亮的散点图
- android - 如何将主题动态添加到芯片视图android