JAVA 多態(運行時多態和編譯時多態)及其內存圖解


定義:某一類事物的多種存在方式(一個對象,兩種形態)

對象的多態:父類或者接口的引用指向其子類的對象

多態的好處:

提高了代碼的擴展性,前期定義的代碼可以使用后期的內容

多態弊端: 前期定義的內容不能使用(調用)后期子類的特有方法(就是多態調用的只能是父類)。但如果是繼承子類覆蓋了父類方法,多態調用的仍是子類的方法!

多態前提:

1、必須有關系(繼承、實現)

2、要有覆蓋

多態實際上是自動類型提升:

Animal a = new cat(); ( cat型自動提升為Animal型(向上轉型,得按Animal對象進行操作),因此cat只能調用Anima類中的方法,cat中特有功能無法訪問 )。如果還想用貓的特有功能,可以強制向下轉型:Cat c = (Cat) a。向下轉型是為了使用特有方法。如果兩者不具備繼承關系不能強制轉換!(向上轉型為了提高擴展性並限制特有方法,向下轉型為了使用特定方法)。對於轉型自始至終都是子類對象做着類型的變化:

盡管f是指向Zi()這個對象,但是實際運行依然是Zi()這個對象調用方法。因此會先去方法區Zi()這個空間中去找方法。若ZI()方法區中沒有則會去找Fu()方法區,再去堆中找相對應的變量。若沒有則在往上找,直到Object類。這其實就是運行時多態,即到底運行Fu()的方法還是Zi()的方法等到程序運行時再去確定。對於多態時的成員函數,總的來說分為三種情況:

1、父類有方法,子類有覆蓋方法:編譯通過,執行子類方法。

2、父類有方法,子類沒覆蓋方法:編譯通過,執行父類方法(子類繼承)。

3、父類沒方法,子類有方法:編譯失敗,無法執行。

方法帶final、static、private時是編譯時多態,因為可以直接確定調用哪個方法。

 

覆蓋與隱藏:

以下來自:https://www.cnblogs.com/it12345/p/5221673.html

隱藏 :child隱藏了parent的變量和方法,那么,child不能訪問parent被隱藏的變量或者方法,但是,講B轉換成A中,可以訪問A被隱藏的變量或者方法

覆蓋 :child覆蓋了parent的變量或者方法,那么,child不能訪問parent被覆蓋的變量或者方法,將child轉換成parent后同樣不能訪問parent被覆蓋的變量或者方法

 

首先看一下JAVA中方法和變量在繼承時的覆蓋和隱藏規則

1.父類的實例變量和靜態變量能被子類的同名變量隱藏

2.父類的靜態方法被子類的同名靜態方法隱藏

3.父類的實例方法被子類的同名實例變量覆蓋

 

還有幾點需要注意的是:

1.不能用子類的靜態方法隱藏 父類中同樣標示(也就是返回值 名字 參數都一樣)的實例方法

2.不能用子類的實例方法覆蓋 父類中同樣標示的靜態方法

3.這點兒請注意,就是變量只會被隱藏 不會被覆蓋 ,無論他是實例變量還是靜態變量,而且,子類的靜態變量可以隱藏 父類的實例變量,子類的實例變量可以隱藏 父類的靜態變量

下圖結果為3就是因為zi自動轉換為Fu類,在zi這個實例的堆內存中找到Fu類num的值。覆蓋只發生在函數上!

 

instance of:

格式:引用  instance of  類/接口

如果給Animal傳入了一只狗但是Animal需要轉換成貓,這是就會發生錯誤。因此需要使用instance of來判斷傳入的引用類型。instanceof 用於判斷對象的具體類型,只能應用於引用數據類型判斷。一般向下轉型時加入instance of判斷增強代碼健壯性。

 

多態成員特點:

 
---------------------
作者:donCoder
來源:CSDN
原文:https://blog.csdn.net/doncoder/article/details/83243906
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM