我听说利斯科夫替换原则(LSP)是面向对象设计的基本原则。它是什么?它的一些使用例子是什么?
当前回答
我建议您阅读这篇文章:违反利斯科夫替换原则(LSP)。
你可以在那里找到一个解释,什么是利斯科夫替换原则,一般线索帮助你猜测你是否已经违反了它,一个方法的例子,将帮助你使你的类层次结构更安全。
其他回答
以Board数组的形式实现ThreeDBoard会有用吗?
也许你想把不同平面上的ThreeDBoard切片作为一个板。在这种情况下,您可能希望为Board抽象出一个接口(或抽象类),以允许多种实现。
就外部接口而言,您可能希望为TwoDBoard和ThreeDBoard提取一个Board接口(尽管上述方法都不适合)。
在一个非常简单的句子中,我们可以说:
子类不能违背它的基类特征。它必须有能力。我们可以说这和子类型是一样的。
可替代性是面向对象编程中的一个原则,它指出,在计算机程序中,如果S是T的子类型,那么类型T的对象可以被类型S的对象替换
让我们用Java做一个简单的例子:
不好的例子
public class Bird{
public void fly(){}
}
public class Duck extends Bird{}
鸭子能飞,因为它是鸟,但这个呢:
public class Ostrich extends Bird{}
鸵鸟是一种鸟,但它不能飞,鸵鸟类是鸟类的一个子类,但它不应该能够使用fly方法,这意味着我们打破了LSP原则。
很好的例子
public class Bird{}
public class FlyingBirds extends Bird{
public void fly(){}
}
public class Duck extends FlyingBirds{}
public class Ostrich extends Bird{}
让我试着考虑一个接口:
interface Planet{
}
这是由类实现的:
class Earth implements Planet {
public $radius;
public function construct($radius) {
$this->radius = $radius;
}
}
你将使用地球作为:
$planet = new Earth(6371);
$calc = new SurfaceAreaCalculator($planet);
$calc->output();
现在再考虑一个扩展到地球的阶级:
class LiveablePlanet extends Earth{
public function color(){
}
}
根据LSP的说法,你应该可以用LiveablePlanet代替Earth,而且它不会破坏你的系统。如:
$planet = new LiveablePlanet(6371); // Earlier we were using Earth here
$calc = new SurfaceAreaCalculator($planet);
$calc->output();
这里的例子
到目前为止,我发现LSP最清晰的解释是“利斯科夫替换原则说,派生类的对象应该能够替换基类的对象,而不会给系统带来任何错误,也不会修改基类的行为”。文中给出了违反LSP的代码示例并进行了修复。