在軟體設計遵循的基本原則的有這麼一條這樣的原則:
多用組合少用繼承!
在物件導向的軟體設計中,對於類的擴充套件,首先想到的是使用類的繼承來實現,由子類繼承父類,從而完成對子類的功能擴充套件。
繼承的好處是可以盡量讓相同的屬性或功能復用。但是隨著專案越來越大,需求不斷編號,繼承就會變得越來越臃腫,後期難以控制和維護。
最重要的是,繼承會不分青紅皂白地把父類的公有和受保護的方法統統繼承下來,而這些方法可能是子類不需要的功能,會對子類產生一些危害!
如果使用組合方式,就不會出現上述繼承問題。所謂物件組合,是指在乙個物件中含有另外乙個物件的引用,從而可以使用該內部物件的引用
作出一些處理行為。
使用組合方式的好處有以下幾點:
首先,不會對類產生有害的影響;
其次,組合方式要比繼承方式靈活,因為是有系統執行動態地決定使用物件與否。
最後,不會造成因繼承而引起的類的膨脹,減少了對父類的依賴性!
以上部分摘抄於《軟體秘笈-設計模式那點事》第一章第四頁!
以下著重介紹一下組合,繼承因為大家都很熟悉所以在此不作為重點介紹!
其實組合大家也都在用,只是不知道其理論而已!
package test;
public class person
public head geth()
public body getb() }
class head
}class body
}
小剛本人是從事網路遊戲行業的,故在此用遊戲相關的業務物件來進行說明!
比如說開發一款角色扮演類的網路遊戲
遊戲中常常會設計到遊戲使用者,遊戲主角色,主角色中的夥伴(寵物,俠客,家將);遊戲npc,遊戲怪物等物件!
1、所有遊戲角色 抽象 ispiriter
/**所有遊戲角色的總抽象*/
public inte***ce ispiriter
2、遊戲主角色 hero
/**遊戲賬戶 與 遊戲角色 1-1 的設計*/
public class hero implements ispiriter
3、遊戲中的怪物
/** 怪物 */
public class monster implements ispiriter
4、遊戲中的夥伴抽象
/**主角色的夥伴抽象 (包括 美人 俠客 靈寵)*/
public inte***ce ihuoban extends ispiriter
5、
/**美人*/
public class beauty implements ihuoban
/**靈寵*/
public class pet implements ihuoban
/**俠客*/
public class xiake implements ihuoban
以上設計還望大家可以指點一下!
再論組合與繼承
在物件導向的程式設計中,建立和使用**最可能採取的一種做法是:將資料和方法統一封裝到乙個類裡,並且使用那個類的物件。有些時候,需通過「組合」技術用現成的類來構造新類。而繼承是最少見的一種做法。
因此,儘管繼承在學習oop的過程中得到了大量的強調,但並不意味著應該盡可能地到處使用它。相反,使用它時要特別慎重。只有在清楚知道繼承在所有方法中最有效的前提下,才可考慮它。為判斷自己到底應該選用組合還是繼承,乙個最簡單的辦法就是考慮是否需要從新類上溯造型回基礎類。若必須上溯,就需要繼承。但如果不需要上溯造型,就應提醒自己防止繼承的濫用。但只要記住經常問自己!
首先解釋一下什麼叫上溯造型!(即子類可以強制轉換成父類)
例如:fight(ispiriter f1,ispiriter f2){}我們可以傳入hero物件和monster物件!這裡傳入的hero與monster物件被轉成了父類,
其方法呼叫的介面是不是就變窄了很多!上溯造型是安全的型別轉換!
下面我們可以用幾個簡單的例子決定在什麼場景中去使用繼承和組合!
/**昆蟲*/
class insect
public int getsize()
public void setsize(int size)
public string getcolor()
public void setcolor(string color)
public void move()
//假設昆蟲必須要先移動一次 到合適為止 才能進行攻擊
public void attack()
}class bee extends insect
/**蜜蜂的移動方式:飛*/
public void move()
public void attack()
}public class maintest1
}
輸出的結果竟然是:
飛到合適位置
飛到合適位置
--發起攻擊
使用組合方式的實現:
class attack implements iattack
@override
public void move()
@override
public void attack()
}class insect
public int getsize()
public void setsize(int size)
public string getcolor()
public void setcolor(string color)
}class bee extends insect implements iattack
public void move()
public void attack()
}public class maintest2
}
總結:
如果乙個類需要向另一類暴露所有方法 或者屬性的 就需要用繼承,而前者為父類,後者為子類 比如上面例子中的
insect(昆蟲)與 bee(蜜蜂)
如果乙個類只需要另乙個類的部分功能或者屬性 則用組合。
本人設計的遊戲業務案例中hero類便是如此!
還有在j2ee 中常用的hibernate 框架的實體類 採用的均是典型的組合方式程式設計!
Java 繼承與組合的區別
根據網路上大家對繼承和組合的討論,我簡單總結以下幾點 1 組合 has a 關係可以顯式地獲得被包含類 繼承中稱為父類 的物件,而繼承 is a 則是隱式地獲得父類的物件,被包含類和父類對應,而組合外部類和子類對應。2 組合關係在執行期決定,而繼承關係在編譯期就已經決定了。3 組合是在組合類和被包含...
Java 組合與繼承的區別
組合和繼承都允許在新的類中放置子物件,組合是顯式地這樣做,而繼承是隱式地做。那兩者之間的區別是怎樣的呢?又該如何選擇呢?很多人對組合理解地還不是很好,所以我們先來理解一下組合 組合技術通常用於想在新類中使用現有類的功能而非它的介面這種情況。以car物件舉例 composition with publ...
Java 繼承與組合的區別
根據網路上大家對繼承和組合的討論,我簡單總結以下幾點 1 組合 has a 關係可以顯式地獲得被包含類 繼承中稱為父類 的物件,而繼承 is a 則是隱式地獲得父類的物件,被包含類和父類對應,而組合外部類和子類對應。2 組合關係在執行期決定,而繼承關係在編譯期就已經決定了。3 組合是在組合類和被包含...