1. 但這還不是全部。
假設該類Cow
有一個printAll()
調用另外兩個方法的方法。然後代碼將像這樣工作:
代碼 | 描述 |
---|---|
|
|
|
屏幕輸出將是:
|
注意,在對像上調用類printAll()
中的方法時,使用的是類中的方法,而不是方法中的方法。Cow
Whale
printName
Whale
Cow
主要的不是編寫方法的類,而是調用方法的對象的類型(類)。
只有非靜態方法可以被繼承和覆蓋。靜態方法不被繼承,因此不能被覆蓋。
這是Whale
應用繼承和方法覆蓋後類的樣子:
|
這是Whale 在應用繼承和方法重寫之後該類的樣子: 我們不知道任何舊printName 方法。 |
2. 類型轉換
這裡還有更有趣的一點。因為一個類繼承了其父類的所有方法和數據,所以對子類對象的引用可以存儲在(分配給)類型與父類(以及父類的父類等)相同的變量中——一直到班級Object
)。例子:
代碼 | 描述 |
---|---|
|
屏幕輸出將是:
|
|
屏幕輸出將是:
|
|
屏幕輸出將是:
方法 toString() 繼承自Object 類 |
這是一個非常有價值的屬性:稍後您將了解如何在實踐中使用它。
3. 調用對象的方法
當在變量上調用方法時,實際上是在對像上調用該方法。這種機制稱為動態方法分派。
它看起來是這樣的:
代碼 | 描述 |
---|---|
|
屏幕輸出將是:
|
|
屏幕輸出將是:
|
請注意,被調用方法的具體實現printName()
——是類中的方法Cow
還是類中的方法Whale
——不是由變量的類型決定的,而是由變量引用的對象的類型決定的。
變量Cow
存儲一個對象的引用Whale
,printName()
類中定義的方法Whale
就是被調用的。
這不是很明顯。記住主要規則:
可在變量上調用的方法集由變量的類型決定。 調用的具體方法實現由變量引用的對象的類型/類決定。
你會一直遇到這個,所以你越早記住越好。
GO TO FULL VERSION