## Java編程那些事兒62——繼承(二)
鄭州游戲學院陳躍峰
出自:[http://blog.csdn.net/mailbomb](http://blog.csdn.net/mailbomb)
##### 8.5.2.3 方法覆蓋
前面介紹了繼承的一些基礎知識,現在介紹一些在使用繼承時需要注意的問題。熟悉這些問題將更好的解決項目中的實際問題。
例如在實際的游戲中,會按照怪物的種類實現設計。首先設計一個基礎類Monster,然后按照怪物類別設計Monster的子類,如Boss、NormalMonster等。則在實際實現時,每個怪物都有移動(move)的功能,但是在Boss和NormalMonster的移動規則存在不同。這樣就需要在子類的內部重新編寫移動的功能,從而滿足實際的移動要求。該示例的實現代碼如下:
~~~
?????????????????? //Monster.java
?????????????????? publicclass Monster{
??????????????????????????? publicvoid move(){
???????????????????????????????????? //移動功能
??????????????????????????? }
?????????????????? }
?????????????????? //Boss.java
?????????????????? publicclass Boss extends Monster{
??????????????????????????? publicvoid move(){
???????????????????????????????????? //Boss類的移動規則
??????????????????????????? }
?????????????????? }
?????????????????? //NormalMonster.java
?????????????????? publicclass [NormalMonster ]()extends Monster{
??????????????????????????? publicvoid move(){
???????????????????????????????????? //NormalMonster類的移動規則
??????????????????????????? }
?????????????????? }
~~~
這樣在Monster的每個子類內部都重新書寫了move方法的功能,這種在子類內部重新父類中的方法的語法現象,稱作方法覆蓋(override)。
方法覆蓋在實際中保持了類的結構的統一,在實際使用時將極大的方便程序開發人員的使用,使項目的整體結構保持統一,便于項目的維護。
在使用子類的對象時,子類內部的方法將覆蓋從父類繼承過來的方法,也就是說子類的對象調用的是子類的功能方法,而不是父類的方法。
在進行方法覆蓋時,子類內部的方法和父類的方法聲明相同,而且子類方法的限制不能比父類的方法嚴格。例如不能使用比父類限制更大的訪問控制符或拋出比父類更多的異常等,這個在實際使用方法覆蓋時需要特別的注意。
在實際的項目中大量的存在需要在子類內部重寫父類的功能方法的地方,恰當的使用方法覆蓋將為項目開發帶來很大的便利。
##### 8.2.2.4 需要注意的問題
除了方法覆蓋以外,在實際使用繼承時還有很多需要注意的問題。下面就這些問題進行一一說明。
1、? 屬性覆蓋沒有必要
方法覆蓋可以重寫對應的功能,在實際繼承時在語法上也支持屬性覆蓋(在子類內部聲明和父類屬性名相同的屬性),但是在實際使用時修改屬性的類型將導致類結構的混亂,所以在繼承時不能使用屬性覆蓋。
2、? 子類構造方法的書寫
該項是繼承時書寫子類最需要注意的問題。在子類的構造方法內部必須調用父類的構造方法,為了方便程序員進行開發,如果在子類內部不書寫調用父類構造方法的代碼時,則子類構造方法將自動調用父類的默認構造方法。而如果父類不存在默認構造方法時,則必須在子類內部使用super關鍵字手動調用,關于super關鍵字的使用將在后續進行詳細的介紹。
說明:子類構造方法的參數列表和父類構造方法的參數列表不必完全相同。
3、? 子類的構造過程
在構造子類時由于需要父類的構造方法,所以實際構造子類的過程就顯得比較復雜了。其實在實際執行時,子類的構造過程遵循:首先構造父類的結構,其次構造子類的結構,無論構造父類還是子類的結構,都是首先初始化屬性,其次執行構造方法。則子類的構造過程具體如下:
如果類A是類B的父類,則類B的對象構造的順序如下:
a)????????類A的屬性初始化
b)????????類A的構造方法
c)????????類B的屬性
d)????????類B的構造方法
由于任何一個類都直接或間接繼承自Object類,所以Object類的屬性和構造方法都是首先執行的。
4、? 不要濫用繼承
在實際的項目設計中,繼承雖然很經常使用,但是還是不能濫用,使用繼承的場合以及相關問題參看下面的說明。
##### 8.5.2.5 如何設計繼承
在實際的項目中,類和類之間的關系主要有三種:
1、? 沒有關系
項目中的兩個類之間沒有關聯,不需要進行消息傳遞,則這兩個類之間就沒有關系,可以互相進行獨立的設計。
2、? 使用關系(has-a)
如果一個類的對象是另外一個類的屬性,則這兩個類之間的關系是使用關系。例如把房屋(House)看作是一個類,把門(Door)看成另外一個類,則房屋有一個門,代碼的實現如下:
~~~
?????????? //House.java
public class House{
??????????????????? public Door door;
?????????? }
?????????? //Door.java
?????????? public class Door{
?????????? }
~~~
則這里Door的對象是House類的屬性,則Door和House類之間的關系就是使用關系,House使用Door類來制作自身。
使用關系提供了使用已有類來聲明新類的方式,可以以組合的方式來構建更復雜的類,這是項目中使用類的常見方式之一。
判斷是否是使用關系的依據就是:has-a,一個類具備另外一個類的對象,例如一個House有一個門。
3、? 繼承關系(is-a)
如果一個類是另外一個類的一種,也就是在分類上存在包含關系,則應該使用繼承來實現。例如Boss是怪物的一種,則使Boss繼承Monster類。
下面簡單介紹一些項目中繼承的設計方法。在實際設計繼承時,一般有兩種設計的方法:
1、? 自上而下的設計
在實際設計時,考慮類的體系結構,先設計父類,然后根據需要來增加子類,并在子類的內部實現或添加對應的方法。
2、? 自下而上的設計
在實際設計時,首先不考慮類的關系,每個類都分開設計,然后從相關的類中把重復的屬性和方法抽象出來形成父類。
對于初學者來說,第二種設計方式相對來說比較容易實現,所以一般初學者都按照第二種設計方式進行設計,設計完成以后再實現成具體的代碼。
- 前言
- (1)序言
- (2)程序設計是什么?
- (3)你適合學習程序設計嗎?
- (4)如何學好程序設計?
- (5)程序設計介紹小結
- (6)計算機軟件基本概念
- (7)進制的概念
- (8)計算機內部的數據表達
- (9)網絡編程基礎
- (10)Java語言簡介
- (11)JDK的獲得、安裝和配置
- (12)第一個HelloWorld程序
- (13)Eclipse基本使用
- (14)Eclipse基礎使用進階
- (15)如何學好Java語法
- (16)代碼框架、關鍵字和標識符
- (17)基本數據類型
- (18)變量和常量
- (19)數據類型轉換
- (20)空白、語句結束和注釋
- (21)算術運算符
- (22)比較運算符
- (23)邏輯運算符
- (24)賦值運算符
- (25)位運算符
- (26)移位運算符
- (27)其它運算符
- (28)運算符優先級
- (29)表達式
- (30)流程控制基礎
- (31)if語句語法(1)
- (32)if語句語法(2)
- (33)if語句語法(3)
- (34)switch語句語法
- (35)while語句語法
- (36)do-while語句語法
- (37)for語句語法
- (38)break和continue語句
- (39)流程控制綜合示例1
- (40)流程控制綜合示例2
- (41)流程控制綜合示例3
- (42)流程控制綜合練習
- (43)數組概述
- (44)數組基礎語法
- (45)數組使用示例1
- (46)數組使用示例2
- (47)數組使用示例3
- (48)多維數組基礎
- (49)多維數組使用示例1
- (50)多維數組使用示例2
- (51)多維數組練習
- (52)方法聲明
- (53)方法聲明示例
- (54)方法調用
- (55)方法重載和參數傳遞
- (56)方法練習
- (57)面向對象基礎
- (58)類(一)
- (59)類(二)
- (60)對象
- (61)面向對象設計方法和面向對象特性(一)
- (62)繼承(二)
- (63)多態性
- (64)訪問控制符、修飾符和其它關鍵字
- (65)static修飾符
- (66)final修飾符
- (67)this和super
- (68)抽象類和接口(一)
- (69)抽象類和接口(二)
- (70)抽象類和接口(三)
- (71)內部類簡介
- (72)包的概念
- (73)JDK文檔使用
- (74)java.lang包介紹1
- (75)String類使用
- (76)StringBuffer類和System類
- (77)包裝類
- (78)時間和日期處理
- (79)Random隨機處理
- (80)集合框架簡述
- (81)異常處理概述
- (82)異常處理語法1
- (83)異常處理語法2
- (84)IO簡介
- (85)IO類體系
- (86)文件操作之File類使用
- (87)文件操作之讀取文件
- (88)文件操作之寫文件
- (89)讀取控制臺輸入
- (90)裝飾流使用1
- (91)裝飾流使用2
- (92)IO使用注意問題
- (93)多線程基礎
- (94)多線程實現方式1
- (95)多線程實現方式2
- (96)多線程使用示例1
- (97)多線程使用示例2
- (98)多線程問題及處理1
- (99)多線程問題及處理2
- (100)多線程問題及處理3
- (101)網絡編程概述
- (102)網絡編程技術1
- (103)網絡編程技術2
- (104)網絡編程技術3
- (105)網絡編程技術4
- (106)網絡編程技術5
- (107)網絡協議概念
- (108)網絡編程示例1
- (109)網絡編程示例2
- (110)網絡編程小結