最近對將子類別物件賦值給父類別物件有點心得,想和大家分享一下.但本人水平有限,請各位指正和批評.
言歸正傳,下面是幾個小例子,請大家看一看.
測試一
父類別:
子類別:
結果:this is 父類別print()方法――此時物件是Subclass@126b249
此時物件是Subclass@126b249
說明:
Supclass sup=new Subclass();
雖然聲明的對像是父類對象,但實際的記憶體空間是子類對象的。
繼承父類別的方法public void print()被調用,輸出的是子類別物件名字解析。
結論:編譯時宣告的物件是父類別對象,但執行時間卻是子類別物件.子類別沒有重寫父類別的方法,則此時的物件呼叫繼承父類別的方法。
測試二
父類別:
子類別:
結果:this is 子類別print()方法――此時物件是Subclass@126b249
此時物件是Subclass@126b249
說明:
我在上個範例的基礎上,重寫了父類別的print()方法,此時的呼叫的是子類別的print()方法。
結論:在上個例子結論的基礎上,我得到了一個結論:此時對象運行時確實子類對象,如果子類沒有從寫父類的方法,
則此時的物件呼叫繼承父類別的方法;否則,此時的物件呼叫子類別方法.
問題: 我們是不是可以從上面的測試得到的這樣結論: 將子類別物件賦值給父類別物件(即Supclass sup=new Subclass()),
我們得到的就是子類別物件,即sup就是子類別物件??????
測試三
父類別:
子類別:
結果:此時的屬性時:父類別屬性
說明:我在第一個測試的基礎上,給父類別添了一個屬性className,在子類別重寫了這個屬性.
但我輸出此時物件的屬性時,卻是父類別的屬性.
結論: 將子類別物件賦值給父類別物件,方法和屬性和我們正統的繼承關係很不一樣.
問題:
此時物件究竟是子類別物件,還是父類別物件?
開始推測:
我在推測之前有幾點須聲明:
1.當我們new一個子類別物件時,父類別物件的建構子同時也被執行,即父類別的一些必要資訊和子類別物件共佔一個記憶體空間,
當我們方法重寫時,於是我們就能使用super這個指代父類別的物件.
2.java中物件並不是完全的物件導向思想做的,即不是把一個物件的屬性和方法同時封裝到物件中.
而是物件有自己的屬性,方法卻是引用類別中的方法,可以說它是把屬性和類別中方法的引用封裝到物件中.
於是物件呼叫的方法不是自己的方法,而是類別中方法.至於java為什麼要這樣做,我就不知道了.
3.當物件被載入到記憶體時,類別先被載入到記憶體中,此後類別應是一隻留在記憶體中.至於類別什麼時候從記憶體中消失,我也不知道.
我想java一定有自己的回收機制,就像回收對像一樣.
4.編譯和與運行是完全不同的事.編譯時主要做的是聲明對象的類型,分配屬性,檢查語法錯誤等
運行時做的是,將物件載入記憶體(一般用new,反射也常用), 運行程式碼執行功能等.
5.若是讀者您和我在這幾點沒有產生共鳴的話,或者說我們在這幾點沒用相同的認識的話,你會覺得我在胡說.
也許你會覺得我的專家分太低,就覺得我的可信程度就低.但我想說的是學不分先後,達者為先.
呵呵,我已準備好將我的專家分變為負值了,不胡扯了,我們繼續.
推測:
1.當我們編譯Supclass sup=new Subclass()時,sup物件被宣告為Supclass類別,於是sup物件的屬性便是父類別物件的屬性的值,
3.接著2繼續,若我們重寫父類別的方法時,由於sup物件的記憶體空間是子類別物件的記憶體空間,子類別的方法public void print()已載入到記憶體中.
所以我們呼叫的是子類別的方法public void print();如果你需要呼叫父類別的被重寫方法,需要用super.
這段話可以對測試二進行解釋.
總結:
以下純粹是個人觀點:
將子類別物件賦值給父類別物件,所得到物件是這樣的一個物件:
它是一個編譯是為父類別物件,但運行卻是一個子類別物件,具體特徵如下.
1.被宣告為父類別物件2.擁有父類別屬性3.佔用子類別的記憶體空間4.子類別方法覆寫父類別的方法時,此時物件呼叫的是子類別的方法;否則,自動呼叫繼承父類別的方法.
5.我人認為這個物件既不是父類別物件,也不是子類別物件.當我們用到它的方法時,
我便把它看成子類別物件;若用到它的屬性時,我把它看成父類別物件.
它是一個佔用父類屬性,而使用子類方法的對象.至於到底是什麼對象,我認為還是得根據聲明來,它應算是父類對象,但擁有子類方法.
想一想:
在測試三的基礎上,我們如何取出子類別的屬性? ? ? ? ?