我是OOP的新手。最近,我读到了《里斯科夫替代原理》。
在下面给出的代码中, Square 类继承了 Give_Area 。假设正方形类与正方形有关(例如有效性检查)。 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
类和两个由Square
派生的Rectangle
和Shape
类。现在Shape
具有(虚拟)方法getArea()
。不管它实际上是什么类型,您都希望它返回(具体,实例化!)形状所覆盖的区域。因此,如果您在getArea()
实例上调用Shape
,则无需关心它是矩形,正方形还是其他可能想到的形状。
答案
没有过载,甚至不需要LSP之类的东西,即答案是否定的,过载和LSP并不矛盾。
该设计
另一方面,正如paxdiablo所指出的,应用LSP取决于设计。就上面的示例而言,这意味着,也许由于某种原因,实际上您是否在乎是否具有矩形。好吧,在那种情况下,LSP说您应该考虑一下您的设计。
您的密码
在这一点上,我不得不承认,我并没有真正了解您的代码所针对的目标。有一个Give_Area
类,它根据uh,pi
的值来计算线圈的面积。第二种方法是计算以Radius
作为对角线的正方形?然后是Square
类。如果Validity()
返回false,那意味着什么?退化的正方形也许?我的建议是:重新考虑您的设计。问问自己“我要处理的类和对象是什么?”和“我想要对现实世界中的物体进行建模吗?”
反例
在Wikipedia(上面的链接)中演示了如何违反LSP。我将尝试弥补第二个例子。假设您有一个带有Car
方法的drive()
类。派生类(RacingCar
,Van
,...)可以指定速度,加速度等。当汽车驶入水中(深水,湖泊,大海)时,汽车将破损,并调用下一个车库。现在,您派生了一个AmphibiousVehicle
类。这不会在水面上摔坏,车库将被无用地召唤。你有预料到吗?也许是吧。但是,如果不是这样,则根据进一步的上下文,我会考虑一个Vehicle
类,它是Car
的基础。它将有一个方法move()
。仍然属于drive()
的Car
将调用move()
,并在发生故障时可能再次调用(-;)车库。等等。