我是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派生的RectangleShape类。现在Shape具有(虚拟)方法getArea()。不管它实际上是什么类型,您都希望它返回(具体,实例化!)形状所覆盖的区域。因此,如果您在getArea()实例上调用Shape,则无需关心它是矩形,正方形还是其他可能想到的形状。

答案

没有过载,甚至不需要LSP之类的东西,即答案是否定的,过载和LSP并不矛盾。

该设计

另一方面,正如paxdiablo所指出的,应用LSP取决于设计。就上面的示例而言,这意味着,也许由于某种原因,实际上您是否在乎是否具有矩形。好吧,在那种情况下,LSP说您应该考虑一下您的设计。

您的密码

在这一点上,我不得不承认,我并没有真正了解您的代码所针对的目标。有一个Give_Area类,它根据uh,pi的值来计算线圈的面积。第二种方法是计算以Radius作为对角线的正方形?然后是Square类。如果Validity()返回false,那意味着什么?退化的正方形也许?我的建议是:重新考虑您的设计。问问自己“我要处理的类和对象是什么?”和“我想要对现实世界中的物体进行建模吗?”

反例

在Wikipedia(上面的链接)中演示了如何违反LSP。我将尝试弥补第二个例子。假设您有一个带有Car方法的drive()类。派生类(RacingCarVan,...)可以指定速度,加速度等。当汽车驶入水中(深水,湖泊,大海)时,汽车将破损,并调用下一个车库。现在,您派生了一个AmphibiousVehicle类。这不会在水面上摔坏,车库将被无用地召唤。你有预料到吗?也许是吧。但是,如果不是这样,则根据进一步的上下文,我会考虑一个Vehicle类,它是Car的基础。它将有一个方法move()。仍然属于drive()Car将调用move(),并在发生故障时可能再次调用(-;)车库。等等。

10-04 20:21