哪种类型的继承更可取?

7

实现第二种情况的唯一目的是如果我想从一个可碰撞对象派生而不是一个对象。如果是这样的话,那么什么情况下第一种情况更有利,因为第二种情况提供了更多的灵活性。

这两个可碰撞对象都只有一个纯虚函数,而Object是可以在屏幕上绘制的对象的基类(在我的情况下)。

^假设我正确理解以下代码(我不太确定)

class Object
class CollidableObject : Object
class Actor : public CollidableObject

class Object
class Collidable
class Actor : public Object, public Collidable

编辑:

根据马特/塞思的意见

class Object
class Collidable
class Clickable
class Trackable
class BlowUppable
class Actor : public Object, public Collidable, public Clickable, public Trackable,
              public BlowUppable

class SomeObjectThatIsTakenForGrantedThatEverythingElseIsInherited : public Actor

第一个例子是第二种情况,第二个例子是第一种情况。我想这是我看到第一种情况的唯一用途。

@Luchian
由于您的回复不是原始问题,因此这将是一个不同的问题。

在这种情况下,将对象从is-a更改为has-a关系是否有区别?在每种情况下,为了检查碰撞,对象必须具有标志以知道是否应该检查碰撞。在您的情况下,可以检查成员是否为空,但在派生情况下,对象本身告诉它是否可以发生碰撞。在数组/树中,我可以将派生对象作为参数传递,或者使用get()方法将hitbox作为参数传递。

更深入地说,我有另一个类-使用第二种情况

class Hitbox : public Object, public Collidable

并且Actor类将其作为成员

class Actor : public Object
{
     Hitbox *box;
};

具有碰撞的对象将拥有一个碰撞框,这个框架可以准确地代表您的岗位。但是仍然让我困惑的是,当我再次审查您的示例时,它是否意味着Hitbox应该拥有一个可碰撞成员?

class Hitbox
{
     Collidable *collision;
};

我所拥有的: 一个演员拥有一个处理碰撞的命中框。
命中框应该做什么: 继承可碰撞或者 拥有一个可碰撞成员
演员已经遵循你的规定。命中框也应该这样吗?
3个回答

2
我会选择第二种方法,因为Object和Collidable是交叉关注点。如果你采用CollidableObject的方法,你可能会得到大量的类组合爆炸。很快你就会看到一个CollidableTrackableClickableBlowuppableObject。
由于Collidable是纯虚函数,在这种情况下它被用作接口,所以没有多重继承的反对意见。你只需说明Actor实现了Collidable接口。

如果你采用第一种方式,就不需要一个 CollidableTrackableClickableBlowuppableObject,而只需从 CollidableTrackableClickableBlowuppable 继承的一个类,就像第一种方式一样,但是你不会像第一种方式那样继承 Object。我不确定第一种方法是否更有用;难道所有的 Clickable 都应该可绘制到屏幕上吗?如果你把它们都分开,你就无法知道你的 Object 是否可点击,或者你的 Clickable 是否可绘制。采用第二种方式,你就知道 Clickable 是可绘制的。 - Seth Carnegie
1
如果你按照我本来想说的做,就不需要有... - Seth Carnegie

1

这是策略模式的完美应用场景。这里英语语言玩弄我们的思维,让我们认为CollidableObject是此层次结构中有效的对象。我认为碰撞更像是一种行为而不是一个对象,所以我不会选择这两个。

对于这个问题,我更倾向于使用组合:

class Object
{
   CollidableBehavior* collisionBehavior;
}
class Actor : Object
{
   // collisionBehavior = new ActorCollision()
}

class AClassThatDoesntCollide
{
   // collisionBehavior = NULL
}

如果碰撞行为取决于Actor类的具体情况,那么这将不太实用。另一方面,如果它是一个独立的属性,那么这就很有意义。 - Mark Ransom

0
实现第二种情况的唯一目的是如果我想从可碰撞的对象中派生而不是从一个对象派生吗?
是的,第二种情况给您更多的灵活性,因为它允许分离接口。例如,以后您可能需要一个可碰撞但不可绘制的对象。
什么时候使用第一种情况比第二种情况更有利呢?因为第二种情况提供了更多的灵活性。
第二种情况提供了更多的灵活性,但设计上也更加复杂。最终,您将需要虚拟继承,这更难处理。然而,如果您的基类是纯抽象的,那就不应该有问题。
您可以查看this

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接