類的繼承實現(xiàn)了is-a關(guān)系,但不適用于has-a關(guān)系。比如學(xué)生和成績的關(guān)系,午餐和青菜的關(guān)系等。一種方案是成為包含、組合或是層次化的關(guān)系;另一種是使用私有或保護繼承。
組合(或包含)關(guān)系,即創(chuàng)建一個包含其它類對象的類。使用組合,類可以獲得實現(xiàn),但不能獲得接口。
實現(xiàn)組合關(guān)系,其初始化通常用成員初始化列表方法。注意用初始化列表包含多個項目時,被初始化的順序為它們被聲明的順序,而不是它們在初始化列表中的順序。
私有繼承,基類的公有成員和保護成員都將成為派生類的私有成員,公有方法都將成為派生類的私有方法。意味著基類方法將不會成為派生類對象公有接口的一部分,但可以在派生類的成員函數(shù)中使用它們。故也是獲得實現(xiàn),但不獲得接口。格式如:
class Student : PRivate std::string, private std::valarray<double>
記住private繼承是默認(rèn)值,如果公有繼承應(yīng)該用public關(guān)鍵字!
使用包含關(guān)系,將提供被顯式命名的對象成員,而私有繼承則提供了無名稱的子對象成員。因此在用成員初始化列表初始化時,私有繼承的版本應(yīng)該使用類名而不是成員名來標(biāo)識構(gòu)造函數(shù)。如要調(diào)用基類方法,包含關(guān)系的版本通過使用對象成員來調(diào)用,而私有繼承版本使用類名和作用域解析運算符來調(diào)用。
綜上,包含和私有繼承都能建立has-a關(guān)系。包含關(guān)系簡單直觀,應(yīng)優(yōu)先使用。而私有繼承有更多特性,如派生類可以使用基類的保護成員;允許派生類重新定義從基類那里繼承的虛函數(shù)等。
保護繼承是私有繼承的變體,關(guān)鍵字為protected,基類的公有成員和保護成員都將成為派生類的保護成員。在第三代類中可以看出保護繼承與私有繼承的區(qū)別。使用私有繼承,第三代類不能使用基類接口,因其在派生類中已經(jīng)變成私有方法;而使用保護繼承,基類公有方法在第二代中變成受保護的,因此第三代類可以使用它們。
|
新聞熱點
疑難解答