2012-07-09 60 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