方法在由子类覆盖的父级中引发异常

时间:2018-10-17 09:36:29

标签: java

如果子类重写了实例方法,为什么引用父类的子类实例需要捕获异常。 这是清晰图片的插图

public class Animal{
  public void printName() throws Exception{
   System.out.println("Animal Method");
  }
}


public class Dog extends Animal{

  public void printName(){
     System.out.println("Dog Method");
  }
  public static void main(String[] args){

    Animal m = new Dog();
    ((Dog)m).printName(); //prints Dog Method
    m.printName(); // this is supposed to be overridden and will print "Dog Method", why the throws Exception of Animal method printName was copied. to the instance

  }
}

3 个答案:

答案 0 :(得分:1)

变量m的引用类型是Animal,因此在编译时,使用了Animal类的方法签名,尽管在运行代码时发生了事件,但实际调用的方法是子类中的方法。 / p>

答案 1 :(得分:1)

这是因为变量m被定义为Animal,并且编译器看到Animal的printName方法引发了异常。

您可能知道,可以在变量上调用的方法由其类型定义,如编译时类型声明:

Animal m;

即使m实际上指向狗,您也只能在m上调用Animal的方法。 (除非您施放)

以同样的方式,它可能抛出的异常也由其声明的类型定义。这就是为什么在对Dog声明的对象调用方法时,不需要捕获异常的原因。

真正有趣的是,派生类中的重写方法只能从 throws 子句中删除异常,或者使其更具体,但不能添加任何异常,因为这会导致对于在基类上调用该方法的人来说,结果出乎意料。

答案 2 :(得分:0)

在编译时m实际上是Animal类型的,所以yo应该捕获Exception,因为检查了Exception并且在编译时没有dog对象,但是在运行时m是Dog类型。因此将调用狗printName方法,但是在这一行((Dog)m).printName()中将其强制转换为Dog,因此不必捕获异常。