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

异常JavaAPI是否违反Liskov原则?

裴硕
2023-03-14

如果S是T的一个子类型,那么T类型的对象可以被S类型的对象替换。

子类有两种不同的行为(选中与未选中),在某些情况下,除非更改当前代码,否则无法用子类对象有效地替换基类用法,例如,如果编写如下代码

try{
     InputStream is = new FileInputStream("C://test.txt");//throws IOException                        
     while((i=is.read())!=-1){
        c=(char)i;            
        System.out.print(c);
     }
  }catch(Exception e){// can not be replaced by any subtype, but IOException
     e.printStackTrace();
  }

这是违反吗?,为什么/为什么不?。

资料来源:http://www.oracle.com/technetwork/articles/entarch/effective-exceptions-092345.html

例2:

给定方法:

public class MyClass {
    public void test() throws Exception{
        // nice stuff
    }
}

客户:

public class MyTest {

    MyClass clazz = new MyClass();

    // 'Exception' can not be changed by a subclass directly
    public void testTest() throws Exception { 
        clazz.test();
    }
}

你告诉我,我可以创建一个子类并覆盖该方法,而不会抛出异常,这是完全有效的,但不是我想向您展示的。

当我说“Exception”不能由子类直接更改时,我的意思是:您不能编写如下内容:

// You can not do this at home
public class MyTest {

    MyClass clazz = new MyClass();

    // hey look!, there is a compiler error!
    public void testTest() throws NullPointerException { 
        clazz.test();
    }
}

共有1个答案

乐正瑞
2023-03-14

LSP意味着您可以在任何需要基类实例的地方使用任何子类实例。并不是说您可以在代码中任意更改类名,就像在“catch”示例中一样。否则,OO程序将无法编写。

你的第二个例子完全不正确。“抛出异常”可以被异常的任何子类替换。这并不是LSP的一个例子。

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

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

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

  • 我有以下代码: 所以我们知道

  • Liskov替换原则指出,您应该编写您的类继承,这样将子类型交换为它们的基类型就不会改变应用程序的行为。 然而,虚拟关键字字面上似乎存在,以允许子类型的行为不同于基类型。虚拟/覆盖关键字(不包括覆盖抽象成员)的大多数使用不可能违反Liskov吗?我觉得这可能比我理解的更微妙。也许这是一个“规则有时会被打破”的情况,或者原则中的“不要有不同的行为”部分有一个灰色地带。

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