這兩天學了多態,自然就涉及到了方法的重寫。在筆者瞎用代碼折騰的過程中,發現報錯類型提到了“This static method cannot hide the instance method from Fu”(如),於是瞭解到除了覆蓋(重寫)外還有隱藏這一回事,各種查資料,終於找到了一個比較詳細的文章,解決了我不少的疑惑。轉寄下,以後可能還少不了返回來看。
1、編譯時間類型和運行時類型
Java的引用變數有兩個類型,一個是編譯時間類型,一個是運行時類型
編譯時間類型:由聲明該變數時使用的類型決定
運行時類型:由該變數指向的物件類型決定
如果編譯時間類型和運行時類型不一致,會出現所謂的多態。因為子類其實是一種特殊的父類,因此java允許把一個子類對象直接賦值給一個父類引用變數,無須任何類型轉換,或者被稱為向上轉型,由系統自動完成。
如 Father f = new Son(); Son是Father的子類
引用變數f就會出現編譯時間類型和運行時類型不一致的情況 編譯時間是Father類型的 運行時是Son類型的
當變數的編譯時間類型和運行時類型不一致時,通過變數訪問它所引用的對象的執行個體時,該執行個體變數的值由聲明該變數的類型決定。
通過變數訪問它所引用的對象的方法時,該方法的行為由所引用的對象實際類型所決定。
2、隱藏和覆蓋
覆蓋:子類重寫父類的方法,要求方法名和參數類型完全一樣(參數不能是子類),傳回值和異常比父類小或者相同(即為父類的子類),存取修飾詞比父類大或者相同。
覆蓋是對於執行個體方法而言的
方法不能交叉覆蓋:子類執行個體方法不能覆蓋父類的靜態方法;
子類的靜態方法也不能覆蓋父類的執行個體方法(編譯時間報錯)
隱藏:父類和子類擁有相同名字的屬性或者方法( 方法隱藏只有一種形式,就是父類和子類存在相同的靜態方法)時,父類的同名的屬性或者方法形式上不見了,實際是還是存在的。
隱藏是對於靜態方法和成員變數(靜態變數和執行個體變數)而言的
(1)當發生隱藏的時候,宣告類型是什麼類,就調用對應類的屬性或者方法,而不會發生動態綁定
(2) 屬性只能被隱藏,不能被覆蓋
(3)變數可以交叉隱藏:子類執行個體變數/靜態變數可以隱藏父類的執行個體/靜態變數
3、隱藏和覆蓋的區別
(1)被隱藏的屬性,在子類被強制轉換成父類後,訪問的是父類中的屬性
在無強制轉換時子類要訪問父類的屬性使用super關鍵字
(2)被覆蓋的方法,在子類被強制轉換成父類後,調用的還是子類自身的方法
子類要是想訪問父類的方法,可以使用super關鍵字
相關文章:
關於java覆蓋equals更深層的方法概述
PHP和JAVA中的重載(overload)和覆蓋(override) 介紹