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

是数组。是否列出违反Liskov替代原则的情况?[副本]

诸葛品
2023-03-14

数组。asList(…) 返回数组周围的列表包装。此包装具有固定大小,并直接由数组支持,因此,对add()或其他试图修改列表的函数的调用将引发UnsupportedOperationException。

开发人员经常对此感到惊讶,stackoverflow中的问题就是明证。

然而,列表接口有一个add()方法,根据Liskov替换原则(LSP),它应该对列表的所有派生器都能正常工作

是数组返回的类型。asList()违反Liskov替换原则的示例?


共有3个答案

上官正志
2023-03-14

如果你从非常专业的角度来考虑,那么这当然是一种违反。LSP指出,坏的设计是继承类不能使用超类方法的设计。但是Java并不总是关心违规行为。正如您所建议的那样,这常常会让开发人员感到困惑。add()方法就是一个例子,remove()也是一个例子。这两种方法都适用于不可变列表,并且不能更改。好的是,至少抛出了一个异常。

进一步阅读:http://c2.com/cgi/wiki?UnmodifiableListIsStupidAndItBreaksLsp

水浩歌
2023-03-14

我认为这并没有违反LSP。

LSP说,实现给定接口的类的所有实例都可以互换使用。

列表的文档。add(和其他变异方法)明确指出,该方法的实现可能会引发不支持操作异常。

投掷

UnsupportedOperationException-如果此列表不支持添加操作

因此,如果要对来自未知源的List实例调用此方法,则需要处理add抛出Unsupport tedoperationExc0019的情况。

如果不这样做,则说明您没有正确使用API。

这并不是说我喜欢这个设计。我认为,试图调用该方法是检测实例上不支持任何给定方法的唯一方法这一事实是垃圾。我的意思是,见鬼,给我们一个isAddSupported()方法(或类似方法)。

我只是不认为以下记录的行为会违反LSP。

戴原
2023-03-14

严格地说,确实如此,因为LSP没有可选接口成员的概念:方法要么是接口的一部分,要么不是接口的一部分。

然而,当Java类库将某些接口方法指定为可选时,它显式地允许违反LSP<代码>列表

本质上,Java库的设计者走了一条捷径:他们没有为可变列表(扩展只读列表)创建单独的接口,而是将操作指定为“可选”。此外,它们还没有为您提供一种方法来测试list实例的只读性,因此您唯一的选择是捕获运行时异常,这是一个非常糟糕的想法。这相当于您必须跟踪列表的来源,并且只有在100%确定列表来源时才执行可选操作。

 类似资料:
  • 我是OOP的新手。最近我读到了关于Liskov替换原理的文章。 在下面给出的代码中,Square类继承Give_区域。假设Square类与Square相关(比如有效性检查)。Give_Area给出正方形的面积(4个顶点位于圆的周长上)和圆的面积。所以,如果给我一个半径,我必须打印圆和正方形的面积(由放置在圆周长上的顶点组成)。为了得到圆的面积,我使用了一个参数。但在求平方面积时没有参数。因此,我在

  • 有人能告诉我下面的例子是否违反了LSP吗? 我有一个例子: 和子类: 和主类: 在此示例中,子类添加名为 的新属性,并通过对其自己的属性 进行附加检查来覆盖方法。 在main方法中,我创建了2个对象。第一个是类型的对象,第二个是类型的对象。 当验证人员时,因为所有前提条件都是正确的,所以它是正确的,但是对于员工,它将抛出< code > IllegalArgumentException ,因为它与

  • 如果S是T的一个子类型,那么T类型的对象可以被S类型的对象替换。 子类有两种不同的行为(选中与未选中),在某些情况下,除非更改当前代码,否则无法用子类对象有效地替换基类用法,例如,如果编写如下代码: 这是违反吗?,为什么/为什么不?。 资料来源:http://www.oracle.com/technetwork/articles/entarch/effective-exceptions-09234

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

  • 我正在阅读为什么Java中的数组协方差不好(为什么数组是协方差的,而泛型是不变的?)。如果是的子类型,则是的子类型。这是一个问题,因为这样的事情是可以做的: 这与“正确”实现的泛型不同。不是的子类型 我试图理解为什么它是坏的本质,并且刚刚读了关于LSP的文章。它有没有违反LSP?似乎没有明显的违规行为。

  • 我刚刚安装了Microsoft代码合同。这是的一部分。NET框架和Visual Studio加载项。它提供运行时检查和定义的合同的静态检查。 该工具有四个警告级别,因此我设置了最高级别。 我已经声明了违反Liskov替换原则的类。 LSP规定: 如果S是T的子类型,则T类型的对象可以替换为S类型的对象,而不改变该程序的任何期望属性 在我的例子中,违规行为是这样的:人=新孩子(23);。我们应该能够