异常JavaAPI是否违反了Liskov原则?
根据java.lang.Exception层次结构: 根据李斯科夫替换原理:。。。如果S是T的子类型,则T类型的对象可以替换为S类型的对象 子类有两种不同的行为(选中与未选中),在某些情况下,除非更改当前代码,否则无法用子类对象有效地替换基类用法,例如,如果编写如下代码:异常JavaAPI是否违反了Liskov原则?,java,oop,exception,solid-principles,Java,Oop,Exception,Solid Principles,根据java.lang.Exception层次结构: 根据李斯科夫替换原理:。。。如果S是T的子类型,则T类型的对象可以替换为S类型的对象 子类有两种不同的行为(选中与未选中),在某些情况下,除非更改当前代码,否则无法用子类对象有效地替换基类用法,例如,如果编写如下代码: try{ InputStream is = new FileInputStream("C://test.txt");//throws IOException
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();
}
这是违法行为吗?为什么
资料来源:
编辑1
例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();
}
}
编辑2
你是说我可以创建一个子类,重写这个方法,不抛出异常,这是完全有效的,但这不是我想要展示给你的
当我说“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();
}
}
LSP意味着您可以在任何需要基类实例的地方使用任何子类实例。并不是说您可以在代码中任意更改类名,就像在“catch”示例中一样。否则,OO程序将无法编写
你的第二个例子完全不正确。“抛出异常”可以被异常的任何子类替换。这并不是LSP的一个例子。可能,但这有关系吗?检查和取消检查异常的全部目的是给程序员一个选择。我个人宁愿被鞭打,也不愿意在任何地方都使用检查异常,但有些程序员喜欢它们。它们都是可丢弃的。你说“不能被任何子类型替换”是什么意思?它可以通过
catch(IOException e)
@Chechus true进行更改,但这是Exception
的不同子类型。我想我不明白(从问题中)的是,它是如何违反利斯科夫替换原则的?它没有违反利斯科夫原则,至于你的“不能被强奸…”是的,它可以。您的参数无效,不是因为您被迫编写另一个catch块或抛出IOE,这并不意味着您不能用任何其他Exception子类替换catch块。@Chechus,您遇到错误是因为您的方法抛出了一个比NullPointerException更广泛的异常。它与LSP无关。请阅读edit2,当我说“subclass”时有一点混乱,现在示例2更准确了。您的edit2仍然与LSP无关。你还是没明白重点。LSP并没有说你可以在程序文本中任意改变类名。它表达了我在回答的第一句话中所说的。您可以在需要基类实例的任何地方使用子类实例。@Chechus,也许您误解了LSP。不再解释EJP了,谢谢您的简单性!。