package inheritance;
class A{
public String display(){
return "This is A!";
}
}
interface Workable{
public String work();
}
class B extends A implements Workable{
public String work(){
return "B is working!";
}
}
public class TestInterfaceObject{
public static void main(String... args){
B obj=new B();
Workable w=obj;
//System.out.println(w.work());
//invoking work method on Workable type reference
System.out.println(w.display());
//invoking display method on Workable type reference
//System.out.println(w.hashCode());
// invoking Object's hashCode method on Workable type reference
}
}
我们知道可以调用的方法取决于我们要调用的引用变量的类型。这里,在代码中,在“w”引用(可工作类型)上调用了work()方法,因此方法调用将成功编译。然后,在“w”上调用display()方法,这会产生一个编译错误,表示找不到显示方法,因为Workable不知道它。然后我们尝试调用Object类的方法,即hashCode(),它产生成功的编译和执行。这怎么可能?任何合理的解释?
答案 0 :(得分:4)
直观的答案是,无论您引用什么接口,实现接口的对象必须是Object
的子类。
JLS的第9.2节专门定义了这种行为:http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.2
如果接口没有直接的超接口,那么接口隐式声明一个公共抽象成员方法m,其中包含签名s,返回类型r和throws子句t,对应于具有签名s的每个公共实例方法m,返回类型为r, throws在Object中声明的子句t,除非接口显式声明具有相同签名,相同返回类型和兼容throws子句的方法。
即。假设所有接口都包含与Object
类中的方法相对应的方法签名。
答案 1 :(得分:2)
我认为这里发生的事情是,尽管w
只知道Workable
,但所有对象都必须来自Object
,所以无论什么类{{} 1}}最终是,它必须有w
方法。
答案 2 :(得分:1)
w.display()
无效的原因是您将引用保存为接口类型。编译器只能看到接口公开的方法。如果您打电话给((B)w).display()
,这将有效。您可以调用hashCode()
,因为编译器足够智能,可以知道接口是由Objects继承的,并且所有对象的超类都是Object