抽象方法中的多态性和检查异常抛出

JCl*_*sic 0 java polymorphism

假设我们有一个Foo包含一个方法的类,该方法可能会抛出IOException.

public abstract class Foo {
    public abstract void foo() throws IOException;
}
Run Code Online (Sandbox Code Playgroud)

但是,当我FooImpl像这样扩展该类时:

public class FooImpl extends Foo {
    public void foo() throws Exception {
        throw new Exception("This cannot throw!");
    }
}
Run Code Online (Sandbox Code Playgroud)

这会导致编译时错误:“覆盖的方法不会抛出 java.lang.Exception”

我理解这是因为覆盖方法“可能只抛出其父方法的已检查异常,以及任何未检查的异常”

为什么会这样呢?为什么我们要禁止自己抛出更广泛的异常?

(我也在寻找解决方法)

谢谢!

Lou*_*man 5

您必须始终能够在使用其超类的任何地方使用子类。这几乎是子类的定义,更普遍地称为Liskov 替换原则

因此,鉴于 的定义,以下必须有效Foo

Foo foo = getFooFromSomewhere();
try {
  foo.foo();
} catch (IOException e) {
  // handle e
}
Run Code Online (Sandbox Code Playgroud)

...因为这与 的定义相匹配Foo

对于这个定义FooImpl,这将工作,因为Exception这是不发IOException都没有处理,并作为检查的异常必须被捕获或者以其他方式处理。