面試題:
一個Java程序的執行要經過編譯和運行這兩個步驟,同時Java又是面向對象的編程語言。當子類和父類存在同一個方法,子類重寫了父類的方法,程序在運行時調用方法是調用父類的方法還是子類的重寫方法呢?
涉及的知識點:
- 1、程序綁定的概念:
通俗的講綁定就是指你調用的方法是綁定在哪個類上的。
例如:父類 Father 有 方法 run();
子類 Son 也有方法 run();
那麼你調用的是哪個類的方法? - 2、靜態綁定:
針對java簡單的可以理解爲程序編譯期的綁定(編譯爲.class文件的過程中就完成了綁定)
java當中的方法被final、static、private修飾的和構造方法必然是靜態綁定。 - 3、動態綁定:
定義:在程序運行時根據具體對象的類型進行綁定。 - 4、關於被final、static、private修飾的方法和構造方法是靜態綁定的理解
private:
被private修飾的類不能被繼承。
final:
final方法雖然可以被繼承,但不能被重寫(覆蓋),雖然子類對象可以調用,但是調用的都是父類中所定義的那個final方法。
static:
static方法可以被子類繼承,但是不能被子類重寫(覆蓋),但是可以被子類隱藏。
(這裏意思是說如果父類裏有一個static方法,它的子類裏如果沒有對應的方法,那麼當子類對象調用這個方法時就會使用父類中的方法。
而如果子類中定義了相同的方法,則會調用子類的中定義的方法。
唯一的不同就是,當子類對象向上轉型爲父類對象時,不論子類中有沒有定義這個靜態方法,該對象都會使用父類中的靜態方法。因此這裏說靜態方法可以被隱藏而不能被覆蓋。這與子類隱藏父類中的成員變量是一樣的。
隱藏和覆蓋的區別在於,子類對象轉換成父類對象後,能夠訪問父類被隱藏的變量和方法,而不能訪問父類被覆蓋的方法)
構造方法:
構造方法也是不能被繼承的(網上也有說子類無條件地繼承父類的無參數構造函數作爲自己的構造函數,不過個人認爲這個說法不太恰當,因爲我們知道子類是通過super()來調用父類的無參構造方法,來完成對父類的初始化, 而我們使用從父類繼承過來的方法是不用這樣做的,因此不應該說子類繼承了父類的構造方法),因此編譯時也可以知道這個構造方法到底是屬於哪個類。