[英]A Request for Simple C++ Composition vs. Inheritance Examples
我試圖了解 C++ 中組合和繼承之間的語法差異。
我希望有人能提供兩個簡單的例子。 一個使用組合的類和一個使用繼承的類的例子。
當然,為什么不呢? 既然我喜歡機器人,那就讓我們做一個可以四處走動和抓取東西的機器人吧。 我們將使用繼承制作一個機器人,並使用組合制作另一個機器人:
class Legs
{
public:
void WalkAround() {... code for walking around goes here...}
};
class Arms
{
public:
void GrabThings() {... code for grabbing things goes here...}
};
class InheritanceRobot : public Legs, public Arms
{
public:
// WalkAround() and GrabThings() methods are implicitly
// defined for this class since it inherited those
// methods from its two superclasses
};
class CompositionRobot
{
public:
void WalkAround() {legs.WalkAround();}
void GrabThings() {arms.GrabThings();}
private:
Legs legs;
Arms arms;
};
請注意,至少在這個例子中, CompositionRobot
通常被認為是更好的方法,因為繼承意味着is-a
關系,並且機器人不是特定種類的Arms
,機器人也不是特定種類的Legs
(而不是機器人has-arms
和has-legs
)。
為了稍微擴展@jeremy-friesner 的答案(並且主要是重用他的代碼),很多時候使用比這更多的類來實現組合。 Legs 和 Arms 類本質上是接口的實現。 這使得注入這些依賴項變得容易,因此在對復合對象進行單元測試時模擬/存根它們。 然后你會有類似的東西(忽略虛擬析構函數......):
class Walker // interface
{
public:
virtual void Walk() = 0;
}
class Legs : public Walker
{
public:
void Walk() {... code for walking around goes here...}
}
class Grabber // Interface
{
public:
virtual void GrabThings() = 0;
}
class Arms : public Grabber
{
public:
void GrabThings() {... code for grabbing things goes here...}
}
class InheritanceRobot : public Legs, public Arms
{
public:
// Walk() and GrabThings() methods are implicitly
// defined for this class since it inherited those
// methods from its two superclasses
};
class CompositionRobot
{
public:
CompositionRobot(Walker& walker, Grabber& grabber)
: legs(walker),
arms(grabber)
{}
void Walk() {legs.Walk();}
void GrabThings() {arms.GrabThings();}
private:
Walker& legs;
Grabber& arms;
};
因此用於腿和手臂的實際實現可以在運行時而不是編譯時設置。
順便說一句,我寫這個只是作為一個答案,而不是對 Jeremy 的答案的評論,以便從代碼格式中受益,因此,如果您想對它進行投票,請也做 Jeremy 的。
HTH
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.