我试图理解C ++中组合和继承之间的语法差异。
我希望有人能提供两个简单的例子。使用组合的类的一个示例和使用继承的类之一。
答案 0 :(得分:3)
当然,为什么不呢?因为我喜欢机器人,所以让我们制作一个可以四处走动并抓住东西的机器人。我们将使用继承制作一个机器人,使用合成制作另一个机器人:
class Legs
{
public:
void Walk() {... code for walking around goes here...}
}
class Arms
{
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:
void Walk() {legs.Walk();}
void GrabThings() {arms.GrabThings();}
private:
Legs legs;
Arms arms;
};
请注意,至少对于此示例,CompositionRobot
通常被认为是更好的方法,因为继承意味着is-a
关系,并且机器人不是特定类型的{{1}并且机器人不是特定类型的Arms
(而是机器人Legs
和has-arms
)。
答案 1 :(得分:3)
要稍微扩展@ jeremy-friesner的答案(并且大部分重复使用他的代码),很多时间的编写是使用更多的类来实现的。本质上,Legs and 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