2012-07-09 87 views
1

可能重复:
Do interfaces inherit from Object class in java接口是“对象”吗?

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 
    } 
} 

正如我们所知,它可以调用的方法取决于参考变量上,我们要调用类型。在这里,在代码中,work()方法在“w”引用(这是可加工类型)上被调用,因此方法调用将成功编译。然后,在“w”上调用display()方法,这会产生一个编译错误,说明没有找到显示方法,因为Workable不知道显示方法。然后我们尝试调用Object类的方法,即hashCode(),这会产生成功的编译和执行。这怎么可能?任何合理的解释?

+2

所有对象都是Java中的Object。这可能是为什么它可以调用Object的方法。我认为有人会引用标准来正确回答这个问题。 – nhahtdh 2012-07-09 02:36:17

+0

要在对象上调用哪些方法取决于引用该对象的引用的类型。这里,Workable类型引用指的是对象,以及Work类型引用如何知道Object类的方法? – PrashantGupta 2012-07-09 02:52:18

+0

因为一切都是'对象'(除了原始类型),引用的类型并不重要。我想这就是它的工作原理。 – nhahtdh 2012-07-09 03:00:16

回答

4

直观的答案是,无论指向哪个接口,实现该接口的对象都必须是一个Object的子类。

的JLS的第9.2节特别定义此行为:http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.2

如果接口没有直接超接口,则接口隐式声明与签名s公共抽象成员方法米,返回类型r和引发子句t对应于具有签名s的每个公共实例方法m,返回类型r,并抛出在Object中声明的子句t,除非具有相同签名,相同返回类型和兼容throws子句的方法由接口明确声明。

即,假定所有接口都包含对应于Object类中的方法的方法签名。

+2

+1用于链接到JLS。 :) – 2012-07-09 03:39:52

+0

谢谢。 我想从JLS中添加更多内容。 如果在m被声明为Object中的final时,接口显式声明了这样一个方法m,这是一个编译时错误。 如果接口声明一个方法的签名与Object的公共方法相同(§8.4.2),但是具有不同的返回类型或不兼容的throws子句,那么就是编译时错误。 这解释了一切。 :) – PrashantGupta 2012-07-09 03:46:17

+0

这个答案也适用于'抽象类{}',我的意思是'抽象类'隐式地声明一个带有签名s的公共抽象成员方法m,返回类型r,并且抛出对应于每个公有实例方法的子句t m与签名s,返回类型r,并抛出在Object中声明的子句t或者'abstract class'是否继承'class Object'的实现? – overexchange 2014-12-09 16:54:49

2

我觉得这里发生了什么是,即使w只知道是Workable,所有对象必须从Object派生,所以不管是什么类w最终,它必须有Object方法。

+0

要在对象上调用哪些方法取决于引用该对象的引用的类型。这里,Workable类型引用指的是对象,以及Work类型引用如何知道Object类的方法? – PrashantGupta 2012-07-09 02:51:22

+0

因为接口是类,并且Java中的所有类都从java.lang.Object继承。所以一个可行的***是一个***对象。 – 2012-07-09 03:38:00

1

原因w.display()不起作用,因为您已将引用保存为接口类型。编译器只能看到接口公开的方法。如果你打电话((B)w).display()这会工作。您可以调用hashCode(),因为编译器足够聪明,可以知道接口是由对象继承的,而且所有对象的超类都是Object

+0

这是'hashCode()',而不是'getHashCode()'。不过,它是C#中的'GetHashCode()'。 – 2012-07-09 03:39:21

+0

我有一个混合语言的问题 – secretformula 2012-07-09 11:03:36

+0

它也发生在我身上。只是注意到它。 :) – 2012-07-09 12:09:38