這個涉及到Java多型實現的原理。(這裡預設你有一點研究)
首先給出定義:
這個方法表中包含所有的 除開私有方法、 final方法 、構造方法和靜態方法之外的所有方法,而且陣列元素排列特性是:首先是Object方法,再是自己的間接父類的方法表,再是自己直接父類的方法表,最後是自己這個類的方法表。
在編譯時,jvm根據引用型別去找自己的類中的方法表中是否含有方法的引用,jvm會先去father類中找是否能匹配到“合適”的方法,如果能則編譯透過,如果沒有則編譯報錯。(這也就是為什麼學Java語法時,父類引用只能呼叫父類存在的方法而不能呼叫僅在子類中存在的方法)
在編譯不報錯的情況下,來到執行時,在執行時,jvm保證了該父類引用指向正確的物件
根據物件(father)的宣告型別(Father)還不能夠確定呼叫方法f1的位置,必須根據father在堆中實際建立的物件型別Son來確定f1方法所在的位置。這種在程式執行過程中,透過動態建立的物件的方法表來定位方法的方式,我們叫做 動態繫結機制 。這種動態繫結機制就實現了多型。
由上面的實現過程可以知道,java的多型只能父類引用指向子類物件。
如果要問為什麼不設計讓java的子類引用指向父類物件,這就涉及到語言設計了,已經不是java多型實現這個範疇,Java之父--詹姆斯·高斯林對這個問題可能最有發言權。
這個涉及到Java多型實現的原理。(這裡預設你有一點研究)
首先給出定義:
多型指的是父類引用可以指向子類物件,同一個引用在呼叫同一個方法時表現出不同的行為特徵。多型的實現分為兩個階段:編譯時和執行時;預備知識:在JVM載入類的同時,會在方法區中為這個類存放很多資訊(詳見《Java 虛擬機器體系結構 》)。其中就有一個數據結構叫方法表。它以陣列的形式記錄了當前類及其所有超類的可見方法位元組碼在記憶體中的直接地址 。這個方法表中包含所有的 除開私有方法、 final方法 、構造方法和靜態方法之外的所有方法,而且陣列元素排列特性是:首先是Object方法,再是自己的間接父類的方法表,再是自己直接父類的方法表,最後是自己這個類的方法表。
在編譯時,jvm根據引用型別去找自己的類中的方法表中是否含有方法的引用,jvm會先去father類中找是否能匹配到“合適”的方法,如果能則編譯透過,如果沒有則編譯報錯。(這也就是為什麼學Java語法時,父類引用只能呼叫父類存在的方法而不能呼叫僅在子類中存在的方法)
在編譯不報錯的情況下,來到執行時,在執行時,jvm保證了該父類引用指向正確的物件
根據物件(father)的宣告型別(Father)還不能夠確定呼叫方法f1的位置,必須根據father在堆中實際建立的物件型別Son來確定f1方法所在的位置。這種在程式執行過程中,透過動態建立的物件的方法表來定位方法的方式,我們叫做 動態繫結機制 。這種動態繫結機制就實現了多型。
由上面的實現過程可以知道,java的多型只能父類引用指向子類物件。
如果要問為什麼不設計讓java的子類引用指向父類物件,這就涉及到語言設計了,已經不是java多型實現這個範疇,Java之父--詹姆斯·高斯林對這個問題可能最有發言權。