簡體   English   中英

確定實際調用哪個重寫方法

[英]Determining which overrides method is actually invoked

例如,將子類對象強制轉換為其超類時

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作為輸出,這顯然意味着該方法的版本在子類中定義(原始超類對象無法“執行”的版本),盡管聲明的類型是超類,是嗎? 因此,即使子類方法是在obj上執行的,當obj.newMethod()時, obj.newMethod()出現編譯錯誤。

基本上,為什么通過超類對象obj調用子類中定義的thisMethod()的版本? 我知道obj的實際類型仍然是Subclass,因此自然應該調用新版本,但是那我不能調用obj.newMethod()嗎?

感謝堆的任何解釋(:

編輯:標題中意為覆蓋*

基本上,為什么通過超類對象obj調用子類中定義的thisMethod()的版本?

因為這基本上就是繼承的要點-它允許重寫實現,而調用代碼無需知道正在使用哪個實現。 InputStream為例-您可以使用InputStream進行編碼,然后無論傳遞了FileInputStreamByteArrayInputStream等,相同的代碼都將起作用。在使用抽象類或接口的情況下,您可能正在調用的方法不在編譯時類型中任何實現-但是可以保證在執行時使用的具體對象類型中有一個實現。

我知道obj的實際類型仍然是Subclass,所以自然應該調用新版本,但是那我不應該能夠調用obj.newMethod()嗎?

否,因為obj編譯時類型為Superclass 區分變量的編譯時類型(確定哪些方法可用)與變量值所引用的對象的執行時間類型(確定實際調用的方法實現)之間的區別非常重要。

那只是一個非常簡短的描述-您應該閱讀一本關於繼承的不錯的Java書,以獲取更多詳細信息。

從理論上講, obj是指向Subclass對象的Superclass引用。

因為編譯器obj只是一個Superclass所以可以調用所有Superclass的方法,例如thisMethod ,編譯器不知道對象的類型,而只是引用的類型,因此編譯器將拒絕newMethod因為它可以不能證明這種方法存在。

但是在運行時,對象的類型用於分配方法,而不是引用的類型,因此thisMethod將解析為Subclass的版本。

現在,如果我們知道運行時對象是Subclass類型,我們想告訴編譯器,我們進行強制轉換:

Subclass subobj = (Subclass) obj;

之后,編譯器知道subobjSubclass類型,並且將接受調用newMethodnewMethod類型newMethod只是編譯器的信息,並且不會更改對象obj任何內容,如果obj不是Subclass則先前的語句將在以下位置拋出ClassCastException :運行。

在這個定義中,超類obj = new Subclass()您只能在超類中公開方法,並且在您聲明將實際上調用Subclass對象的聲明時將調用任何方法將調用子類實現

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM