我是OOP的新手.最近我读到了Liskov Substitution Principle.
在下面给出的代码中,Square类继承了Give_Area.假设Square类有与广场相关的事情(如有效性检查). Give_Area给出方形区域(4个顶点位于圆周上)和圆形区域.因此,如果给出一个半径,我将打印圆形和正方形的区域(由放置在该圆周边的顶点组成).为了获得圆形区域,我使用了一个参数.但是在获得正方形区域时没有参数.因此我在这里做了重载.
#include<iostream>
#include<cmath>
using namespace std;
class Give_Area
{
public:
double Radius;
double Area(double pi)
{
return pi*Radius*Radius;
}
double Area()
{
double temp = sqrt(2.0)*Radius;
return temp*temp;
}
};
class Square : public Give_Area
{
public:
bool Validity()
{
//checking validity
}
};
int main()
{
Give_Area* area = new Square();
area->Radius = 3.0;
cout<< "Area of Circle: " << area->Area(3.14159) <<endl;
cout<< "Area of Square: " << area->Area() <<endl;
return 0;
}
我的问题是……
Is this overloading violating Liskov Substitution Principle?
如果这个代码违反了,那么有人请给我一个超载的例子,它不会违反Liskov替换原则吗?
我搜索了我的查询但没有找到任何结果. 🙁
提前致谢.
最佳答案 LSP
Liskov’s Substitution Principle(或LSP)是关于抽象的.想象一下一个类Shape和两个派生自Shape的Square和Rectangle.现在Shape有一个(虚拟)方法getArea().你会期望它返回(具体的,实例化的!)形状覆盖的区域,而不管它实际是什么类型.因此,如果您在Shape实例上调用getArea(),则无需关心它是矩形,正方形还是您能想到的任何其他形状.
答案
在没有过载的情况下甚至不需要类似LSP的东西,即答案是否定的,重载和LSP不矛盾.
该设计
另一方面,正如paxdiablo指出的那样,应用LSP取决于设计.就上面的例子而言,这意味着,也许出于某种原因,你实际上是在关心你是否有一个矩形.那么,在这种情况下,LSP说你应该考虑你的设计.
你的守则
我不得不承认,在这一点上,我并没有真正得到你的代码所针对的目标.有一个Give_Area类根据呃,pi的值计算一个cirle的面积.第二种方法计算一个以半径作为对角线的正方形?然后是Square类.如果Validity()返回false,那意味着什么?一个堕落的广场可能吗?我的建议是:重新考虑你的设计.问问自己“我想要处理的类和对象是什么?”和“我想要的真实物体是什么样的模型?”
反例
维基百科(上面的链接)演示了如何违反LSP.我将尝试编写第二个例子.假设您有一个带有方法驱动器()的类Car.派生类(RacingCar,Van,…)可以指定速度,加速等.当汽车驶入水中(深水,湖泊,海洋)时,汽车将会断裂并且下一个车库被召唤.现在你派出了一个类AmphibiousVehicle.这个没有在水上打破,车库将被调用,没有用.你有没有期待?也许是吧.但如果没有,根据进一步的背景,我会考虑一个类车辆,它是汽车的基础.它会有一个方法move().并且仍然属于Car的drive()将调用move()并且可以在遇到问题时调用(再次;-))车库.等等.