根据java.lang.Exception层次结构:
并且给定Liskov替换原则: ...如果S是T的子类型,则类型T的对象可以替换为S类型的对象...
对于子类(Checked vs Unchecked)我们有两种不同的行为,并且在某些情况下我们无法有效地用子类对象替换基类使用,除非我们更改当前代码,例如,如果我们编写类似的代码:
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();
}
}
你告诉我,我可以创建一个子类并覆盖该方法而不抛出异常,这是完全有效的,但不是我想要告诉你的。
当我说'异常'不能直接由子类改变,我的意思是:你不能写出类似的东西:
// 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();
}
}
答案 0 :(得分:4)
LSP意味着您可以在任何需要基类实例的地方使用任何子类实例。并不是说您可以在代码中随意更改类名称,就像在' catch'例。否则,OO程序将是不可写的。
你的第二个例子仅仅是错误的。 '抛出异常' 可以替换为Exception的任何子类。并不是说它是LSP的一个例子。