问题标签 [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 投票
35 回答
446835 浏览

oop - Liskov 替换原则的一个例子是什么?

我听说 Liskov 替换原则 (LSP) 是面向对象设计的基本原则。它是什么,有哪些使用示例?

0 投票
5 回答
8307 浏览

c# - C#接口实现关系只是“Can-Do”关系?

今天有人告诉我,C#中的接口实现只是“Can-Do”关系,而不是“Is-A”关系。这与我长期以来对 LSP(Liskov Substitution Principle)的信念相冲突。我一直认为所有继承都应该意味着“Is-A”关系。

所以,如果接口实现只是一个“可以做”的关系。如果有一个接口“IHuman”和“IEngineer”,一个类“Programmer”继承自“IHuman”和“IEngineer”怎么办?当然,“程序员”是“IHuman”和“IEngineer”。

如果只是“Can-Do”关系,是否意味着我们不能期望“Programmer”实例的行为在被视为 IHuman 和被视为 IEngineer 时可能会有所不同?

0 投票
6 回答
6853 浏览

c# - 接口继承:你怎么看这个:

在查看我们的代码库时,我发现了一个类似于以下模式的继承结构:

Class2Method1投掷NotImplementedException

问题:

  • 您一般如何看待继承接口?
  • IBase之间的关系是否Class2违反了里氏替换原则?
0 投票
2 回答
1600 浏览

c# - Liskov 替换和组合

假设我有这样的课程:

而且我想扩展它以添加超出扩展方法可以做的东西......我唯一的选择是组合:

虽然这可行,但工作量很大......但是我仍然遇到了一个问题:

我可以在这里传入一个 Foo,但不能传入一个超级 Foo,因为 C# 不知道 SuperFoo 在 Liskov 替换意义上确实符合条件......这意味着我通过组合扩展类的用途非常有限。

所以,修复它的唯一方法是希望原始 API 设计者留下一个接口:

现在,我可以在 SuperFoo 上实现 IFoo(因为 SuperFoo 已经实现了 Foo,只是改变签名的问题)。

在完美世界中,使用 Foo 的方法会使用 IFoo 的:

现在,由于通用接口,C# 理解了 SuperFoo 和 Foo 之间的关系,一切都很好。

最大的问题是 .NET 封装了许多偶尔会很好扩展的类,而且它们通常不实现通用接口,因此采用 Foo 的 API 方法不会接受 SuperFoo 并且您不能添加重载.

所以,对于所有的作曲爱好者来说......你如何绕过这个限制?

我唯一能想到的就是将内部的 Foo 公开,这样你可以偶尔通过它,但这似乎很乱。

0 投票
2 回答
438 浏览

oop - Zend_Form 和 Liskov 替换原则

我看到的一个非常常见的模式(我选择 Zend Framework,只是因为我在这个问题的那一刻正在处理它),是这样的:

Zend_Form 不是一个抽象类,但完全可以单独使用。这似乎被“推荐”为将您的表单“封装”成一个不错的类的地方。

这是否违反了 Liskov 替换原则?Zend_Form 的每个子类都将具有与基类截然不同的行为。为此使用组合会更好,还是我完全误解了这个原则?

0 投票
8 回答
17481 浏览

oop - 从矩形导出正方形是否违反了 Liskov 的替换原则?

我是设计和学习设计原则的新手。

它说从矩形导出正方形是违反里氏替换原则的典型例子。

如果是这样,正确的设计应该是什么?

0 投票
2 回答
2145 浏览

c# - 为什么我不能使用 AddRange 添加子类项?

我有两个类.... Parcel 和 FundParcel ...我正在尝试将子类型的 IEnumerable 转换为超类型的 IList ....

这些在另一个类中的方法中使用如下:

我不明白的是为什么不能将 foreach 语句简化为:

我基本上得到一个错误,上面写着“参数类型'System.Colection.Generic.IEnumerable<FundParcel>' is not assignable to parameter type 'System.Collections.Generic.IEnumerable<Parcel>'"

但如果是这样的话,那么我不明白为什么 parcels.Add 有效......

我觉得整个方法应该可以用以下行替换:

...或者也许该方法可以一起废弃,因为子类型应该可以替代它们的超类型..

谁能解释在这种情况下与 AddRange 的关系以及为什么在这种情况下可能需要 for 循环?

0 投票
1 回答
655 浏览

c# - C#.NET中liskov原理的类型参数约束

我尝试创建一个继承 System.ICloneable 接口但 Clone() 方法的返回类型为 T 的通用接口。当然,T 类型需要约束以确保它是 System.Object 类的继承,但是以下代码不起作用。

我究竟做错了什么?

以下约束也不起作用:

  1. 其中 T : System.Object
  2. 其中 T :类

在这种情况下,我如何使用 Liskov 原则来缩小返回类型来解决这个问题?

PS:对不起我的英语,如果我犯了错误。我不是以英语为母语的人。

0 投票
2 回答
989 浏览

solid-principles - SOLID Liskov 替换原则

如果我有类似的东西

这是否意味着我永远不应该使用 square 和 triangle 类而只参考图形?

就像从不这样做:

0 投票
4 回答
3479 浏览

design-patterns - 复合模式是 SOLID 吗?

复合模式中的叶子实现了组件接口,包括Add叶子永远不会使用的方法RemoveGetChild这似乎违反了接口隔离原则。

那么 Composite Pattern SOLID的用法是什么?

复合模式链接:http: //www.dofactory.com/Patterns/PatternComposite.aspx