如果子类重写了实例方法,为什么引用父类的子类实例需要捕获异常。 这是清晰图片的插图
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
}
}
答案 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
,因此不必捕获异常。