重写的方法不能抛出exceptionJava
这是我的代码块。
class Alpha{ public void Gamma() { System.out.println("Alphas"); } } class Beta extends Alpha{ public void Gamma() throws Exception //Line 1 { try { System.out.println("Betas"); } catch(Exception e) { System.out.println("Exception caught"); } finally { System.out.println("xfg"); } } public static void main(String[] args) throws Exception { Alpha g = new Beta(); g.Gamma(); } }
此代码无法编译,因为我在Line1中添加了“throws”。
编译器抱怨重写的方法不能抛出exception。
为什么这样 ?。
为什么不能重写方法抛出exception?
因为我可以通过在子类的实现中添加n行代码来覆盖基类中的方法。
这些添加的代码可以抛出一个exception,为什么我不能在重写方法中使用“throws”?
重写的方法可以抛出exception,只要被覆盖的方法也抛出相同的exception。 您无法引入新的例外。
那你为什么不能引入一个新的例外呢?
OOP的核心概念之一是使用抽象类型,并且所有子类型都可以被视为抽象类型。 见Liskov替代原则
您不能引入更广泛行为的原因是,如果抽象类型(超类或接口)中的方法不会抛出exception并且您将对象称为该类型,则会出现意外行为:
Alpha alpha = new Beta(); // At this point, the compiler knows only that we have an Alpha alpha.myMethod();
如果Alpha的myMethod()
没有抛出exception,但Beta会抛出exception,我们可能会在上面的代码中遇到意外的exception。
子类overriden方法只能抛出(Declare) 未经检查的exception,如ArrayIndexOutOfBoundsException。
但是您不能抛出(声明)已检查的exception。 像IOException。
verriden方法的示例抛出exceptionJava
class A{ public void show(){ // some code here } } class B extends A{ public void show() throws ArrayIndexOutOfBoundsException{ // some code here } }
希望这些可以帮到你。
您的客户端总是考虑处理基本版本。 这就是多态性的全部好处=>客户端忽略了覆盖的一个。
因此,没有什么会强迫客户端处理由覆盖所做的特定规则,这里是由覆盖方法抛出的潜在exception的情况。
这就是为什么覆盖方法不能抛出更广泛的exception。 这会破坏合同。
因此,关于这个逻辑,规则是: Overriden方法CAN(如果需要)只抛出在基本版本中声明的exception的子部分但是不能抛出更宽的部分。
规则说
“子类重写方法不能抛出比超类方法更多的exception”。
编译器抱怨重写的方法不能抛出exception
不,不。 再次阅读该消息。 它表示你不能抛出一个未被声明被重写方法抛出的exception。 根本不是一回事。
您在main方法中的上述代码
Alpha g = new Beta(); //现在它创建了一个新的Beta类的实际对象,并引用了Alpha
g.Gamma(); // *现在编译器看起来只有Gamma()方法在Alpha类中提供了它在Beta类中出现的默认情况下它仍然通过inheritance。但是编译器只查看类Alpha并且问一个问题是包含一个方法Gamma()并找到答案是的,它有。
假设java编译器提供的工具在Beta类的 gamma()方法中抛出更多已检查的exception,那么将会发生什么
-
现在在编译时编译器只依赖于类Alpha的Gamma()方法。它不强制处理此exception或抛出这个错误,因为它可能抛出(假设java编译器允许在重写方法中抛出更多的已检查exception)。 但实际上编译器不会对抛出exception以及可访问性修饰符进行限制。
因为非静态方法调用发生在实际的对象方法而不是类型上,我们给任何超类型,并且在编译时编译器只检查该类型的已分配类的可访问性和存在性。
所以我认为这就是这个被超越的合同背后的原因
•方法定义不能缩小方法的可访问性,但可以扩展它。 •方法定义只能抛出超类中重写方法的throws子句中指定的全部或全部或已检查exception(包括其子类)的子集。