5

我是 OOP 的新手。最近我读到了 Liskov Substitution Principle。

在下面给出的代码中,Square类继承了 Give_Area。假设Square类与 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;
}

我的问题是..

Is this overloading violating Liskov Substitution Principle?

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

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

提前致谢。

4

1 回答 1

2

语言服务提供商

Liskov 的替换原则(或 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()。派生类 ( RacingCar, Van, ...) 可以指定速度、加速度等。当汽车驶入水中(深水、湖泊、大海)时,汽车将破裂并调用下一个车库。现在你派生一个类AmphibiousVehicle。这个不会在水上破裂,而且车库会毫无用处地被调用。你期待吗?也许是的。但如果不是,根据进一步的上下文,我会考虑一个Vehicle作为Car. 它会有一个方法move()。如果遇到麻烦,drive()哪个仍然属于Car会呼叫move()并且可能会呼叫(再次;-))车库。等等。

于 2014-12-17T09:15:38.430 回答