当前位置: 首页 > 知识库问答 >
问题:

Liskov代换原理与流

廖招
2023-03-14

存在无法写入或查找的流派生类这一事实是否违反了Liskov替换原则?

例如,无法查找NetworkStream,如果调用方法Seek,它将抛出NotSupportedException

还是因为存在CanSeek标志就可以了?

考虑到众所周知的Square继承自矩形的例子...将标志DoesHeightAffectsWidthDoesWidthAffectsHeight添加到矩形是否可以解决问题?

这难道不是打开了通过添加旗帜来解决问题的大门吗?

共有2个答案

赏梓
2023-03-14

可以 方法意味着不会破坏LSPStream提供了读、写和查找功能,但不能保证任何实现类都会遵守该功能。可以 方法使这成为契约的一个显式特性-派生类必须实现它们,以允许客户端代码在调用之前检查派生类是否实现了某些行为。因此,任何试图写入的代码都应该在调用write之前选中CanWrite,例如,这可以通过的任何正确实现的派生来完成。因此,它们是可互换的,正如LSP所要求的。

我认为,添加方法来标记派生类是否实现特定功能可能会被滥用,这是肯定的——如果一个团队没有纪律约束,他们可能最终会得到一个非常广泛、臃肿的接口,破坏ISP。我认为StreamIList

我认为在从矩形继承正方形的情况下,您当然可以添加DoeshightAffectSwidthDoeshightAffectSheight来解决问题,但是团队必须决定这是否可以接受,或者添加这些方法是否会破坏ISP。添加AreaLLInternalAlangSequal以支持梯形是否过远?在某种程度上,这取决于编写代码的工程师。

赫连骏
2023-03-14

CanSeek从技术上防止流类违反LSP。只有当它回归真实,寻求才有可能成功。

我个人认为它是ISP和可能SRP的严重弯曲,而我的内部设计人员更喜欢类似于“代码> SekababFiels子类/接口,可搜索流可以从中继承。但我相信这也会带来问题(例如,在有时只能看到的流中)。。。坦率地说,现实世界的可用性胜过原则。

这是需要记住的。偶尔,原则和现实会发生冲突。坚实的原则在大多数情况下有助于最小化不必要的复杂性,并且通常保持OO系统的可维护性,防止它们在自身的压力下崩溃。如果纯粹导致了一个更为复杂的系统,比如说,因为现在一个偶尔可以看到的流并不适合层次结构,那么也许偶尔有一点丑陋是有道理的。

但它不应该仅仅因为法律条文允许就成为第一选择。坚实的原则不仅仅是规则;它们是原则。它们是文字背后的理念——法律的精神。如果你在律师为你的灵魂辩护时坚持字面意思,你就失去了原则的全部意义。

至于正方形/矩形问题...从技术上讲,具有决定改变高度是否也会改变宽度的属性/函数,可以被认为符合LSP的字母。然而,这又一次感觉像律师,并且正在推动其他坚实原则的界限。从现实的角度来看,这也绝对不是一个最佳解决方案,因为它增加了复杂性,并引入了意外副作用的可能性;现在所有想说的rect。Height=50;也会无意中改变宽度。

 类似资料:
  • 我在派生类中重写了带有附加先决条件的虚拟函数。这是快照- 如果我理解正确的话,这里的代码通过附加一个先决条件打破了Liskov替换-IsImmediateProcess和其他日期检查。对吗?或者一个被重写的函数调用一个基函数,然后向它添加自己的行为,这样可以吗? 我不能将重写方法中由初始过程类型引入的条件移动到基本类型,因为它是特定于初始过程的。 在这种情况下,如果派生类重写行为并希望在不违反Li

  • 我试图理解Liskov替换原理,我有以下代码: 我不确定这是否违反了它。原理是,如果你有一个类S的对象,那么你可以用另一个类T的对象来代替它,其中S是T的一个子类。但是,如果我写了 这当然会产生编译错误,因为Vehicle类没有openDoor()方法。但这意味着我不能用它们的父类Vehicle替换VehicleWithDoors对象,这似乎违反了原则。那么这个代码是否违反了它?我需要一个好的解释

  • 在创建我的班级结构时,我努力坚持利斯科夫替代原则。我想在Day类中存储一组日历项。需要有几种不同类型的日历项,例如: 任命项目 备注项目 轮换项目 它们都共享一些抽象基类CalendarItem中的常见功能: 但例如RotaItem有一些额外的功能: 其他类也添加了自己的逻辑等。 我有一组CalendarBaseItem用于我的日课: 但在回顾这一点时,我可以看到我正在打破LSP原则,因为我必须检

  • 我试图通过反复阅读维基百科条目来确定我对上述原则的理解。 撇开仍然让我悲伤的协变和逆变的概念不谈,wikipedia还提到超类型的不变量必须保留在子类型和历史约束或历史规则中。基于最后两个概念,我提出了一个小例子: 所以我的问题是:基于上述两个概念,我用这个例子是否违反了原则?若否,原因为何? 事先非常感谢。

  • 来自维基百科, Liskov的行为子类型概念定义了对象的可替代性概念;也就是说,如果S是T的子类型,则程序中T类型的对象可以替换为S类型的对象,而不改变该程序的任何期望属性(例如正确性)。 假设以下类层次结构: 基本抽象类-。它有一个只读属性,在后继程序中被重写。 基类的继承者-,它重写并返回灰色。 Cat的继任者-,它覆盖并返回带条纹的。 然后我们声明一个方法,参数类型为(不是)。 向该方法发送