有一个很好的例子,在圆-椭圆问题中违反了Liskov替换原理。
下面是一个流行的SO答案的措辞(尽管是矩形和正方形):
在数学中,正方形
是一个矩形
。实际上,它是矩形的特化。“is a”使您希望使用继承来对此进行建模。但是,如果在代码中使Square
派生自Rectangle
,那么Square
应该可以在任何需要Rectangle
的地方使用。这导致了一些奇怪的行为。
想象一下,您的矩形基类上有SetWidth
和SetHeight
方法;这似乎完全符合逻辑。但是,如果矩形引用指向Square
,则SetWidth
和SetHeight
没有意义,因为设置一个将更改另一个以匹配它。在这种情况下,Square没有通过Liskov替换测试与矩形
,让Square继承矩形的抽象是一个坏的抽象。
我的问题是-如果我们在Square
中覆盖setWidth
,并使用将width
和height
设置为相同值的实现,为什么它仍然违反LSP?
它确实违反了它,因为您promisesetWidth()
将设置宽度,而setHeight()
将设置高度。正方形
将打破矩形
做出的这一(隐含的)promise。
我认为是这样的,因为子类在被替换时的行为不像基类,而且它抛出了一个RuntimeException? 我不完全确定,我想知道我的假设是否正确
我正在详细学习LSP,我确实理解为什么强化先决条件违反了这一原则(使用来自http://www.ckode.dk/programming/solid-principles-part-3-liskovs-substitution-principle/#contravariance): 在这里,我清楚地看到,对于基类有效的东西对于它的派生类将失败。换句话说,在不改变行为的情况下,我无法用基类的导数替换
现在,让我们来看看“燃料”类: 以上是完成的所有抽象类,现在让我们看看具体的实现。首先,fuel的两个具体实现,包括一些贫血接口,以便我们可以正确地键入-提示/嗅探它们: 最后,我们有了车辆的具体实现,它确保使用正确的燃料类型(接口)为特定的车辆类别加油,如果不兼容则抛出异常: null
这是在一次采访中问我的。 我回答他说,对于相同的输入集,父母和孩子都应该产生相同的输出集。如果子节点想要扩展父节点的功能,它应该只在父节点支持范围之外的新输入上执行。这样,孩子将维持其父母签订的合同。 我给他举了一个例子,一个api可能正在使用这样的父级 如果这个孩子在这里产生了不同的输出,那么这个孩子就违反了它的父母签订的合同。 他对我的回答不满意,并告诉我这是简单的压倒一切,不违反LSP。所以
缩放最常用的应用之一,就是在水平方向或垂直方向拉伸一个圆,把它变成椭圆。本节,我们将通过平移和横向上拉伸画布上下文,再绘制圆,来创建一个椭圆。 图4-10 圆变换为椭圆 绘制步骤 按照以下步骤,绘制一个椭圆: 1. 定义画布上下文: window.onload = function(){ var canvas = document.getElementById("myCanvas"); va
基础示例 <vuep template="#example"></vuep> <script v-pre type="text/x-template" id="example"> <template> <div class="amap-page-container"> <el-amap vid="amapDemo" :zoom="zoom" :center="c