2017-06-10 55 views
0

當一個子類對象被澆鑄到它的父類,例如確定哪個覆蓋方法實際上被調用

Superclass obj = new Subclass(); 

和類被定義

public class Superclass{ 
    public void thisMethod(){ 
     System.out.println("Superclass version was executed"); 
} 

public class Subclass extends Superclass{ 
    public void thisMethod(){ 
     System.out.println("Subclass version was called"); 
} 
    public void newMethod(){ 
     System.out.println("blah"); 
    } 
} 

obj.thisMethod()被稱爲,我得到Subclass version was called作爲輸出,這顯然意味着ve雖然聲明的類型是超類,但在子類(原始超類對象不能「執行」的版本)中定義的此方法的rsion被調用,但是? 因此,如果即使子類方法在obj上執行, 當調用obj.newMethod()時,我也會遇到編譯錯誤。

基本上,爲什麼在子類中定義的thisMethod()版本是通過超類對象obj調用的?據我所知,obj的實際類型仍然是子類,所以很自然地,新版本應該被調用,但是,那麼我不應該能夠調用obj.newMethod()

編輯:

爲任何解釋(感謝堆意味着覆蓋*在標題

回答

7

基本上,爲什麼是在子類中定義的thisMethod()的版本通過超類對象OBJ被調用?

因爲這基本上繼承的地步 - 它允許實現覆蓋,而無需調用代碼需要知道正在使用的實現,請InputStream作爲。一個例子 - 您可以使用InputStream進行編碼,然後無論您通過FileInputStreamByteArrayInputStream等,相同的代碼都可以使用。在抽象類或接口的情況下,您可能正在調用不具有的方法在編譯時類型中的任何實現 - 但是可以保證在執行時會使用具體對象類型的實現。

我明白obj的實際類型仍然是子類,那麼自然,新的版本應該被調用,但後來,我不應該能夠調用obj.newMethod()

沒有,因爲編譯時objSuperclass。區分確定哪些方法等是可用的變量的類型,以及變量的值引用的對象的類型(確定哪些方法實現是實際的)是非常重要的調用。

這只是一個非常簡短的描述 - 你應該閱讀一本很好的Java書的關於繼承的章節以獲取更多細節。

0

超類obj =新的子類()在這個定義中,你只能在超類中暴露的方法。並且在您的聲明中實際指向子類對象時,您將調用任何方法時它將調用子類實現

1

理論上obj是指向Subclass對象的Superclass參考。

對於編譯器obj只是一個Superclass因此所有的Superclass的方法可以被稱爲例如,編譯器不知道對象的類型,僅僅是引用的類型,因爲編譯器會拒絕newMethod,因爲它不能證明這個方法存在。

但是在運行時,對象的類型用於調度方法而不是引用類型,所以thisMethod將被解析爲Subclass的版本。

現在,如果我們知道運行時對象是Subclass類型的,我們要告訴編譯器,我們做了轉換:

Subclass subobj = (Subclass) obj; 

之後,編譯器知道subobjSubclass類型,並且將接受調用newMethod,該轉換隻是編譯器的一個信息,不會改變對象中的任何內容obj,如果obj不是Subclass以前的語句會在運行時拋出ClassCastException

相關問題