超载是否违反《里斯科夫替代原则》?

Muk*_*t09 5 c++ liskov-substitution-principle solid-principles

我是OOP的新手。最近,我读到了《里斯科夫替代原理》。

在下面给出的代码中,Square类继承了Give_Area。假设Square类与平方有关(例如有效性检查)。Give_Area给出正方形的面积(4个顶点在一个圆的周长上)和一个圆的面积。因此,如果给我一个Radius,我必须打印圆和正方形的区域(由放置在该圆的周长上的顶点组成)。为了得到一个圆的面积,我使用了一个参数。但是获取平方面积时没有参数。因此,我在这里做了重载。

#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;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是..

Is this overloading violating Liskov Substitution Principle?
Run Code Online (Sandbox Code Playgroud)

如果此代码违反了,那么有人可以举一个不违反Liskov替代原则的重载示例吗?

我用谷歌搜索查询,但什么都没找到。:(

提前致谢。

Tob*_*obi 3

LSP

里氏替换原理(LSP)是关于抽象的。想象一个类Shape和两个类SquareRectangle从 派生Shape。现在Shape有一个(虚拟)方法getArea()。您会期望它返回被(具体的,实例化的!)形状覆盖的区域,无论它实际上是什么类型。因此,如果您调用getArea()一个Shape实例,您不必关心它是矩形、正方形还是您能想到的任何其他形状

答案

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

该设计

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

你的代码

在这一点上我必须承认,我真的不明白你的代码的目标。有一个类Give_Area根据 的值计算圆的面积pi。第二种方法计算一个以Radius对角线为的正方形?然后是Square课程。如果Validity()返回 false,那意味着什么?也许是一个退化的正方形?我的建议是:重新考虑你的设计。问问自己“我想要处理的类和对象是什么?” 以及“我想要建模的现实世界对象是什么?”

反例

维基百科(上面的链接)演示了如何违反 LSP。我将尝试举出第二个例子。假设你有一个Car带有方法的类drive()。派生类 ( RacingCar, Van, ...) 可以指定速度、加速度等。当汽车驶入水中(深水、湖泊、大海)时,汽车会损坏并调用下一个车库。现在您派生一个类AmphibiousVehicle。这个不会在水里破裂,车库会被调用而没有任何用处。你期待吗?也许是吧。但如果没有,根据进一步的上下文,我会考虑一个Vehicle作为Car. 它会有一个方法move()。哪个drive()仍然属于Car会打电话move()并且可能会打电话(再次;-))车库以防出现麻烦。等等。