【发布时间】:2010-12-03 22:33:07
【问题描述】:
如果我有类似的东西
class square : figure {}
class triangle : figure {}
这是否意味着我永远不应该使用 square 和 triangle 类而只参考图形?
永远不要这样做:
var x = new square();
【问题讨论】:
标签: solid-principles liskov-substitution-principle
如果我有类似的东西
class square : figure {}
class triangle : figure {}
这是否意味着我永远不应该使用 square 和 triangle 类而只参考图形?
永远不要这样做:
var x = new square();
【问题讨论】:
标签: solid-principles liskov-substitution-principle
在您的情况下,LSP 意味着从figure 继承的所有行为都应该适用于square 或triangle。所以你不希望有 figure.Side1、Side2 和 Side3 的设置器,因为这些对于 square 没有意义。
在某些时候,您必须参考square 或triangle,但仅限于您所做的事情特定于子类的情况。如果您正在实现对所有图形同样适用的行为(可能是 Draw 方法),那么它应该接受 figure 参数而不是 square 或 triangle。
例如,您的类可能设置如下:
abstract class figure
{
abstract void draw();
}
class triangle : figure
{
void draw()
{
// ...
}
}
class drawer
{
void call_draw(figure fig)
{
fig.draw();
}
}
只要figure.draw() 是虚拟的,这意味着它的实现可以(或必须)被子类覆盖,即使对象被用作figure,您也可以执行triangle 的draw() 行为.
【讨论】:
您必须定义 square 和 triangle 类并实现它们的方法 - 而且您必须能够构造它们,正如您所指出的:
var x = new square();
square 和 triangle 的大多数(如果不是全部)其他用途应该通过基类 figure.
关于LSP,这里指的是其他类中以figure为参数的其他方法:
other_method(figure fig);
这个方法应该很高兴工作,无论是square 还是triangle 实例都传递给它,它不应该为了工作而尝试发现实际的类。
【讨论】: