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