问题标签 [liskov-substitution-principle]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
124 浏览

inheritance - 里氏替换原则

我能够大致了解 LSP 及其违规行为。比如说,Square 扩展具有 setWidth() 和 setHeight() 函数的 Rectangle 是对 LSP 的微妙违反,因为有一个额外的要求。类似地,GreenDuck 扩展了具有函数 something(Grass g) 的 Duck 类,不能有额外的子句要求草是绿色的。

对于正方形和矩形场景,我认为实现多边形接口和矩形和正方形类以自己的方式实现多边形是正确的。对于 GreenDuck 场景,GreenDuck 使用组合将 Duck 作为其字段之一可能是一个好主意。

Q1) 我对上述两种情况的理解是否正确?

Q2)另外,我无法模拟 LSP 允许“扩展”的场景,这让我想到了这个问题。有人可以深入研究 LSP 并提供具体的例子,哪些扩展是合适的,如果它是一些组合不会那么好的东西,那么它会带来什么好处。

编辑:为清楚起见

0 投票
3 回答
1425 浏览

c# - 代码契约和继承(覆盖方法的前提条件)

目前,代码协定不允许对派生类中的成员设置先决条件,其中成员已经在基类中设置了先决条件(我实际上目前收到警告而不是错误)。我不明白这背后的逻辑。我知道这与 Liskov 的替换规则有关,即派生类应该始终能够在预期父类的地方使用。当然,“使用”意味着按预期工作。对于接口,这对我来说似乎没问题,因为实现接口的不同类型不会添加状态,因此可以完全遵守合同。但是,当您从基类继承时,您这样做是为了添加状态和特殊功能,而且覆盖方法通常会有额外的要求。为什么可以'

看看下面:

您可能会争辩说,这个类层次结构违反了 Liskov 的规则,因为无线扬声器在传递给期望Speaker. 但这不就是我们使用代码合约的原因吗?确保满足要求?

0 投票
1 回答
61 浏览

php - 这是违反 LSP 的 (php) 吗?

0 投票
1 回答
133 浏览

java - 为什么这个 C++ 代码片段中没有显示违反 Liskov 替换原则的情况?

我正在尝试使用 C++ 类继承来违反 Liskov 替换原则,但无法复制由 Java 程序演示的 LSP 违规导致的相同问题。Java 程序的源代码可以在这个页面上找到。违规会导致页面上描述的错误。这是我在 C++ 中对该代码的翻译:

正如 Rectangle 类所期望的那样,答案是 50。我对 Java 的翻译是错误的,还是与 Java 和 C++ 的类实现之间的差异有关?我的问题是:

  1. 是什么导致了这种行为差异(在我的代码的幕后/问题下)?
  2. 可以在 C++ 中复制 LSP 违规的 Java 示例吗?如果是这样,怎么做?

谢谢!

0 投票
1 回答
1026 浏览

c++ - 重载是否违反里氏替换原则?

我是 OOP 的新手。最近我读到了 Liskov Substitution Principle。

在下面给出的代码中,Square类继承了 Give_Area。假设Square类与 Square 相关(如有效性检查)。Give_Area给出正方形的面积(圆周上有 4 个顶点)和圆的面积。因此,如果给定一个Radius,我必须打印圆形和正方形的面积(由放置在该圆形周边的顶点组成)。为了获得圆的面积,我使用了一个参数。但是获取正方形面积时没有参数。因此,我在这里完成了重载。

我的问题是..

如果此代码违反了,那么有人可以给我一个不会违反 Liskov 替换原则的重载示例吗?

我用谷歌搜索了我的查询,但什么也没找到。:(

提前致谢。

0 投票
2 回答
1011 浏览

scala - 为什么在 Scala 中用 `def` 覆盖 `var` 是不可能的?

虽然我理解为什么 avar不能覆盖val子类中的 a ,反之亦然,但我无法理解为什么 Scala 不允许def子类中的 a 覆盖var超类中的 a

既然var是可变的,为什么不允许 adef覆盖它?谁能帮助我理解这一点?

0 投票
0 回答
191 浏览

c++ - LSP:继承与组合

我需要在支持多种数据类型(不能使用模板)的同时尊重 LSP,并且我在继承和组合之间进退两难。如果我使用继承,则基类不能单独使用,必须每次都强制转换。这是否违反了 LSP?

继承将是:

使用合成时,它看起来像:

0 投票
1 回答
95 浏览

c++ - 继承 C++ 接口和 LSP 违规

我有这样的界面

我有一组“设备”类,所有这些类都需要支持上述接口,以便我可以检查设备之间的兼容性。为此,我从上述 IVersion 类公开继承了每个设备。

现在,由于我继承自 IVersion(以及 Liskov 替换原则),这意味着设备版本。但我想要的实际关系是设备有一个版本。

我希望所有设备都支持 IVersion 中的方法,但我认为我这样做的方式是不正确的。任何人都可以提出更好的方法吗?我可以使用组合,但是现在我需要在 IVersion 中添加方法,将其添加到设备基类中,然后在内部使用 IDevice 实现。这是完成我想要实现的目标的最佳方式吗?

0 投票
1 回答
46 浏览

java - ID和EAN继承可能违反里氏替换原则

我的应用程序有一个设计问题。

我有一个产品和一个类别。两者都必须有身份证。

类别可以有任何正整数作为 ID。(-> 身份等级)

产品必须有一个介于 8 和 13 个密码之间的正整数作为 ID。(-> Ean 级)

因为这是这些类做的唯一事情(创建一个 id)和一个带有正确检查的 getter/setter。

为了减少代码(DRY),我让 Ean 从 Id 继承。但这不会违反 Liskov (LSP) 吗?

我的问题:

  1. 我的 LSP 推理是否正确?如果是:
  2. 我应该通过创建界面来解决它吗?(似乎是重复的代码)还是有其他解决方案?

提前致谢!

标识符.java

Ean.java

0 投票
1 回答
6268 浏览

solid-principles - 什么是拒绝遗赠?

有人可以解释拒绝遗赠是什么意思吗?我尝试阅读一些文章并说它是一种代码气味,或者在 wiki 中它告诉它是一个覆盖基类方法的类,其方式是派生类不遵守基类的合同。

但简而言之,或更简单的说法,它实际上是什么?