我正在阅读一个简单遗传的例子,并且遇到了一个基本概念:一个正方形是一个基本类型,一个矩形是从一个正方形派生出来的。
设置方形尺寸的示例使用了名为Size
的属性。
然后,矩形的示例继续使用Width
和Height
。
这在我的头脑中没有意义,所以我编码了。
问题似乎是在访问rectangle
时,总会出现一个名为“Size
”的令人困惑的属性。
我做对了吗?或者有没有办法在查看Size
时隐藏其他类看rectangle
?
public class square
{
public int Size { get; set; }
public square(int size)
{
this.Size = size;
}
}
public class rectangle : square
{
public int Width { get { return base.Size; } set { base.Size = value; } }
public int Height { get; set; }
public rectangle(int width, int height)
: base(width)
{
Height = height;
}
}
答案 0 :(得分:13)
你是100%正确的,这是向后继承。相反,您应该从Square
类继承Rectangle
类,因为正方形是一种特殊的矩形。
然后,你会得到像
这样的东西public class Rectangle
{
public int Width { get; private set; }
public int Height { get; private set; }
public Rectangle(int width, int height)
{
if (width <= 0 || height <= 0)
throw new ArgumentOutOfRangeException();
Width = width;
Height = height;
}
}
public class Square : Rectangle
{
public int Size
{
get
{
return Width;
}
}
public Square(int size)
: base(size, size)
{
}
}
答案 1 :(得分:8)
问题是矩形不正方形 - 您甚至不能说Square
是Rectangle
因为这会导致很多问题Rectangle
(通常)提供了独立设置宽度和高度的方法 - 这将由Square
约束 - 这是对Liskov substition principle.的经典违规 - 引自维基百科:
违反LSP的典型示例是派生的Square类 来自Rectangle类,假设存在getter和setter方法 宽度和高度。 Square类总是假设宽度 等于高度。如果在上下文中使用Square对象 在期望Rectangle的地方,可能会发生意外行为,因为 Square的尺寸不能(或者不应该)被修改 独立。这个问题不容易修复:如果我们可以修改 Square类中的setter方法,以便它们保留 方形不变(即保持尺寸相等),然后是这些方法 会削弱(违反)矩形制定者的后置条件, 哪个状态可以独立修改尺寸。违规 像这样的LSP,在实践中可能是也可能不是问题, 取决于实际的后置条件或不变量 期望由使用违反LSP的类的代码。可变性是一个 关键问题在这里。如果Square和Rectangle只有getter方法(即 它们是不可变对象),然后不会发生违反LSP的行为。
答案 2 :(得分:3)
遇到了一个基本思想,即一个正方形是一个基本类型,一个矩形是从一个正方形派生出来的。
问题是这是假的 -
正方形是特定类型的矩形,但矩形不是正方形。
话虽这么说,制作方形继承矩形也很危险,因为你最终会出现意想不到的情况。这是common violation of the Liskov Substitution Principle,这就是让Square
和Rectangle
同时实现公共基类(例如Shape
)更好的原因,它只包含共享的属性这两个类,例如Area
或Bounds
等等。
答案 3 :(得分:2)
我认为问题是几何问题: - )
矩形不是正方形。 正方形是一个矩形。
你应该反转继承,你会发现矩形只有Width和Height,而square有一个名为Size的附加属性。
再见 马可
答案 4 :(得分:0)
正方形总是一个矩形,但矩形并不总是正方形 - 因此Rectangle
应该是Square
的父级,而不是相反。< / p>
答案 5 :(得分:0)
几何101:正方形是矩形,但矩形不是正方形。
答案 6 :(得分:0)
Square和Rectangle是违反Liskov substitution principle的典型示例。在这个原则中,两者都没有直接相关,但可能与一个形状有关,例如。
例如:
public class Rectangle
{
public int width {get;set;}
public int height {get;set;}
public int Area() { return width * height; }
}
public class Square : Rectangle
{
public override int width
{
get { return base.width; }
set { base.height = value; base.width = value; }
}
//... etc ...
}
[Test]
public void Rectangles_area_should_equal_length_times_width()
{
Rectangle r = new Square();
r.height = 10;
r.width = 15;
Assert.That(r.Area() == 150); // Fails
}
你看到了问题吗?从基类引用方块时,行为会以意外方式更改。正确的解决方案是Square和Rectangle是兄弟姐妹(Shape的孩子),而不是父母/孩子。
答案 7 :(得分:0)
请参阅有关隐藏继承成员的问题,您可以使用new
修饰符:
public class Rectangle : Square {
private new int Size { get; set; }
...
}