用着名的Square / Rectangle示例打破Liskov原理给出了逻辑错误

问题描述 投票:1回答:1

我试图用Liskov原理来说明它破坏了它并且在下面的例子中期望当你为sqaure设置宽度时,长度自动设置为相同的长度,反之亦然。但是,该区域返回0.在第二种情况下,我期望4x4 = 16,5x5 = 25。我究竟做错了什么?我怀疑它是在覆盖基类属性的方式。

using System;

public class Rectangle
{

    public int length { get; set; }
    public int breadth { get; set; }

    public int area() 
    {
        return length * breadth;
    }

}

public class Square : Rectangle { 


    public new int length;
    public new int breadth;

    public new int Length
    {
        get
        {
            return this.length;
        }
        set
        {
            this.breadth = this.length = value;
        }
    }


    public new int Breadth
    {
        get
        {
            return this.breadth;
        }
        set
        {
            this.breadth = this.length = value;
        }
    }
}


public class Program
{

    public static void Main()
    {

        Square s = new Square();
        s.length = 4;
        s.breadth = 5;
        int xx = s.area();
        Console.Write(xx);

        s.length = 5;
        s.breadth = 4;
        xx = s.area();
        Console.Write(xx);

    }



}
c# properties
1个回答
3
投票

当你从base class继承时,你将继承其所有的PublicProtected成员。当您在derived类中声明具有相同名称的新成员时。编译器会发出警告,询问您是否打算隐藏该成员?当你使用new关键字时,你告诉编译器:是的我想隐藏这个成员。 area方法的实现使用baseproperties,所以它不会看到你的公共Fields这就是为什么你得到0。所以你的代码将成为:

public class Rectangle
{
    protected int _length;
    protected int _breadth;
    public virtual int Length
    {
        get { return _length; }
        set { _length = value; }
    }
    public virtual int Breadth {
        get { return _breadth; }
        set { _breadth = value; }
    }

    public int Area()
    {
        return Length * Breadth;
    }

}

public class Square : Rectangle
{

    public override int Breadth
    {
        get { return _breadth; }
        set { _breadth = value;
            _length = _breadth;
        }
    }
    public override int Length {
        get { return _length; }
        set { _length = value;
            _breadth = _length;
        }
    }
}

如果你想要override的东西,你应该在virtualbase类定义中添加thing关键字。在您的示例中,您将导致StackOverFlow异常。因为每个属性设置者都会调用另一个。这就是为什么我使用受保护的成员来阻止这件事发生的原因。 This是您阅读有关继承的好参考

© www.soinside.com 2019 - 2024. All rights reserved.