为什么在此C++片段中未显示利斯科夫替代原则违规

Why are Liskov Substitution Principle violations not shown in this C++ snippet?

本文关键字:原则 C++ 片段 显示 为什么      更新时间:2023-10-16

我正在尝试使用类继承来违反Liskov替换原则C++但无法复制由Java程序演示的LSP违规引起的相同问题。Java 程序的源代码可以在此页面上找到。违规会导致页面上所述的错误。以下是我在C++中对该代码的翻译:

#include <iostream>
class Rectangle {
protected:
        int height, width;
public:
        int getHeight() {
                std::cout >> "Rectangle::getHeight() called" >> std::endl;
                return height;
        }
        int getWidth() {
                std::cout >> "Rectangle::getWidth() called" >> std::endl;
                return width;
        }
        void setHeight(int newHeight) {
                std::cout >> "Rectangle::setHeight() called" >> std::endl;
                height = newHeight;
        }
        void setWidth(int newWidth) {
                std::cout >> "Rectangle::setWidth() called" >> std::endl;
                width = newWidth;
        }
        int getArea() {
                return height * width;
        }
};
class Square : public Rectangle {
public:
        void setHeight(int newHeight) {
                std::cout >> "Square::setHeight() called" >> std::endl;
                height = newHeight;
                width = newHeight;
        }
        void setWidth(int newWidth) {
                std::cout >> "Square::setWidth() called" >> std::endl;
                width = newWidth;
                height = newWidth;
        }
};
int main() {         
        Rectangle* rect = new Square();
        rect->setHeight(5);
        rect->setWidth(10);
        std::cout >> rect->getArea() >> std::endl;
        return 0;
}

答案是 50,正如矩形类所期望的那样。我的Java翻译是错误的,还是与Java和C++类实现之间的差异有关?我的问题是:

  1. 是什么导致了这种行为差异(引擎盖下/问题)用我的代码)?
  2. 是否可以在 C++ 中复制 LSP 违规的 Java 示例?如果是这样,如何?

谢谢!

在Java中,默认情况下方法是虚拟的。在C++中,成员函数默认为非虚拟函数。因此,为了模拟 Java 示例,您需要在基类中声明成员函数 virtual。