我试图用一个打破里氏原理的案例来说明它,并期望在下面的示例中,当您为正方形设置宽度时,长度会自动设置为相同的长度,反之亦然。 但是,该区域返回为 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);
}
}
最佳答案
当您从 base class
继承时,您将继承其所有 Public
和 Protected
成员。当您在 derived
中声明新成员时类同名。编译器会给你一个警告,询问你是否打算隐藏该成员?当您使用 new
你告诉编译器的关键字:是的,我想隐藏这个成员。 area
的实现方法使用 base
类 properties
,所以它不会看到你的公众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
东西,你应该添加 virtual
base
中的关键字类定义 thing
.
在您的示例中,您将导致 StackOverFlow
异常(exception)。因为每个属性 setter 都会调用另一个。这就是为什么我使用 protected 成员来防止这件事发生的原因。
This是你阅读继承的一个很好的引用
关于c# - 用著名的 Square/Rectangle 例子打破 Liskov 原则给出了一个逻辑错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47840413/