2016-03-28 70 views
-2

下面是一個示例。將派生對象引用分配給基類變量將不起作用

Class A { 
    Method A(); 
    Method B(); 
    Method C(); 
} 
// A and B are not interfaces 

Class B extends A { 
    Method C(int); 
} 

Class Harness { 
    A ob = new B(); 
    ob.C(3); 
} 

IDE抱怨ob.C(3)不能對方法在C因爲AC期望沒參數製成。但據我所知,我正在撥打方法CB

據我所知,變量類型決定了被調用的對象的方法集,但是實際的對象決定了將被調用的確切方法。那爲什麼它不工作?

+0

撇開你的代碼是不可編譯的......你的類'B'有一個'C'方法。所以調用'new B()。C()'是完全正確的。這不能有任何編譯器錯誤。因此我投票結束不清楚。請編輯您的問題,並提供一個可編輯的示例,正​​確解釋您遇到的問題。 – Seelenvirtuose

+0

我編輯了這個問題。請看看它。謝謝。 –

+0

@RajeevSingh *「C可以這樣調用ob.C(3);,代碼看起來很好」*這是錯誤的,而'ob.C(3)'''不起作用。 – Tom

回答

3

您已將類型B的對象分配給A類型的變量。 A類別上沒有方法C,編譯器正在抱怨,因爲它必須鏈接到基於變量聲明的類型的方法 - 即A。除非A類型具有某種方法C的聲明,否則編譯器無法知道在引用A類型時調用該方法是安全的。

+0

是不是它的對象本身將確定將被調用的確切方法? –

+0

只在一定程度上。編譯器不允許調用任何*方法 - 只有在變量類型上定義的方法。子類實例*可能*重寫一個方法,並且這將是在運行時調用的方法,但方法簽名必須爲與該變量關聯的類型聲明。 – sisyphus

0

您已經聲明new B是的A和一個實例沒有方法C得到它的工作,你沃爾德必須重新至少投出您ob它B.所以assumig這是一個僞代碼,這會工作:

A ob=new B(); 
    ((B)ob).C(); 
+0

我在類B中調用方法C(int a)而不是類A中的方法。 –

+0

在你的情況中,儘管事實上'ob'確實是'B'類的實例,你將它聲明爲'A的實例'所以你只能訪問'A'類型的方法和字段。要到達'B'成員,必須明確地將你的'ob'強制轉換(「重新聲明」)爲'B'類。這很簡單。 – Antoniossss

+0

這是有道理的。謝謝。 –

2

正如您在您的問題本身中提到的那樣,變量的類型決定了可以使用它調用的所有方法。在你的例子中,class A沒有簽名爲C(int)的方法。它只有一個簽名爲C()的方法。所以,B中的方法C(int)甚至不是重寫的方法。這是一種重載的方法。

運行時多態僅適用於重寫的方法。

您必須讓class AC(int)方法才能成功編譯此代碼。

相關問題