我是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替换原则的超载示例吗?
我搜索了我的查询但没有找到任何结果。 :(
提前致谢。
答案 0 :(得分:2)
Liskov's Substitution Principle(或LSP)是关于抽象的。想象一下,课程Shape
和两个课程Square
和Rectangle
派生自Shape
。现在Shape
有一个(虚拟)方法getArea()
。你会期望它返回(具体的,实例化的!)形状覆盖的区域,而不管它实际是什么类型。因此,如果您在getArea()
实例上致电Shape
,您无需关心它是矩形,方形还是您能想到的任何其他形状< / em>的
没有重载甚至不需要类似LSP的东西,即答案是否定的,重载和LSP不矛盾。
另一方面,正如paxdiablo指出的那样,应用LSP取决于设计。就上面的例子而言,这意味着,可能由于某种原因你实际上做关心你是否有一个矩形。那么,在这种情况下,LSP说你应该考虑你的设计。
我必须承认,在这一点上,我并没有真正得到你的代码所针对的目标。有一个类Give_Area
根据呃pi
的值来计算一个圆圈的面积。第二种方法计算一个以Radius
为对角线的正方形?然后是Square
类。如果Validity()
返回false,那意味着什么?一个堕落的广场可能吗?我的建议是:重新考虑你的设计。问问自己“我想要处理的类和对象是什么?”和“我想要的真实物体是什么模型?”
维基百科(上面的链接)展示了如何违反LSP。我将尝试编写第二个例子。假设您有一个方法Car
的课程drive()
。派生类(RacingCar
,Van
,......)可以指定速度,加速等。当汽车驶入水中(深水,湖泊,海洋)时,汽车会断裂,下一个车库叫。现在您派生了一个类AmphibiousVehicle
。这个没有在水上打破,车库将被调用,没有用。你有没有期待?也许是吧。但如果没有,根据进一步的背景,我会考虑Vehicle
的基础Car
。它将有一个方法move()
。 drive()
仍属于Car
的{{1}}会调用move()
并可能会在遇到问题时调用(再次;-))车库。等等。