2013-01-17 95 views
-3

我有這樣的代碼:呼叫子類方法通過超類引用

String stringRef = new String("Java");     // (1) 

System.out.println("(2): " + stringRef.getClass());  // (2) 
System.out.println("(3): " + stringRef.length());   // (3) 

Object objRef = stringRef;        // (4) 

// System.out.println("(5): " + objRef.length());   // (5) Not OK. 
System.out.println("(6): " + objRef.equals("Java")); 

爲何無法調用線length()(5);在第(6)行中將調用equals()這個類?

回答

0

你不能這樣做,因爲子類的方法不在你的超類中。在這種情況下,儘管String是Object的子類,因爲length()未在java.lang.Object類中聲明,但它的實例不可能調用長度。然而

equals()方法被重寫的串類,因此字符串的equals()將被調用

+0

我知道這一點。但爲什麼......因爲通過對象objRef = stringRef;我們正在將stringreference賦值給objReference ..意味着現在objRef指向與stringRef相同。 – mainu

+0

但在編譯期間它的對象引用很重要。 equals()然而在你的子類String中被覆蓋,因此是由於運行時多態性String的equals()在運行時被調用 – PermGenError

1

equals被宣佈Object,所以你可以調用它; length不是。編譯器將不會嘗試確定objRef引用的對象類型;它只有知道它是一個對象時才起作用。

Java編譯器根據點運算符左側的表達式的靜態類型,靜態解析要調用的方法的簽名。多態性和動態分派的概念僅適用於調用覆蓋方法的分辨率。

0

對於編譯器,objRefObject一個實例,其不具有名爲length()任何方法。另一方面,equals()是一種來自Object的方法,並且在String中繼承,這就是程序行爲正確的原因。

0

length()方法對於字符串是唯一的。通過將其分配給對象,Java不再知道它是一個String。

舊的clichè:所有的圈子都是形狀,並不是所有的形狀都是圓圈。

如果你這樣做了以下它將工作:

System.out.println("(5): " + ((String)objRef).length()); 

在這裏,你強制轉換爲字符串,然後再調用長度()。

0

當你有一個Type參考,你只能調用Type超小號的方法或訪問字段是公開的,可見Type,的即Type自己的方法或公共的。

在這種情況下,Object定義了方法equals和其他許多方法,因此您可以使用它們。

0

它是引用的類型而不是實際的對象,它定義了所有可以訪問的方法。所以你無法使用超類引用訪問子類方法,儘管你的超類引用持有一個子類對象。

+0

但是它是對象的類型,而不是定義哪個函數被綁定以防你重寫方法的引用超類並調用該方法。 – Renjith