我目前有一个'WorldObject'类,它包含一个指向b2Body的指针,以及几个方法和变量。
但是让WorldObject成为b2Body的派生类并不聪明吗?
这类事情的一般方法是什么?要始终在类中创建最重要对象的派生类,还是只创建一个新类并创建所有属性?
这些可能性有哪些优点和缺点?
谢谢。
答案 0 :(得分:3)
没有最好的办法。这完全取决于具体情况:
指向b2Body
的指针实现了合成关系,即WorldObject
具有b2Body
。
使WorldObject
派生自b2Body
实现继承,并且仅在WorldObject
为b2Body
时才会执行。这意味着原则上您可以使用WorldObject
对象执行使用b2Boby
(以及更多)执行的所有操作。
经验法则是preferring composition over inheritance。除非你真的有明显的继承。
在你的情况下,b2Body
是一个僵硬的身体。现在问你一个问题:你的对象是一个身体吗?或者你的对象是一个身体?
更实用:这种设计的优势在于它将Box2D引擎的选择封装在WorldObject
中。这使您可以在以后使用其他API将软件移植到另一个物理引擎时更好地控制影响。如果您使用继承,则底层引擎API将显着影响您自己软件的设计,并使其有一天很难迁移到另一个引擎。
答案 1 :(得分:2)
做作文通常更好,不要过度使用继承。
另请注意,您通常会创建一个调用module.exports = {
main: {
files: [{
expand: true,
cwd: "build/css/",
src: "style.css",
dest: "../"
}]
},
}
的正文,并返回b2World::CreateBody()
,并且继承是不可能的。
为了避免内部b2Body*
的生命周期问题,您可以使用智能指针。我使用这个定义:
b2Body*
然后,在我的class BodyDeleter
{
public:
BodyDeleter()
:m_world(NULL)
{}
BodyDeleter(b2World *world)
:m_world(world)
{}
void operator()(b2Body *body)
{
if (m_world)
m_world->DestroyBody(body);
}
private:
b2World *m_world;
};
typedef std::unique_ptr<b2Body, BodyDeleter> b2BodyPtr;
:
WorldObject
然后,在class WorldObject
{
protected:
WorldObject(b2World *world)
:m_body(NULL, m_world)
{}
b2BodyPtr m_body;
};
的实际子类中:
WorldObject
答案 2 :(得分:0)
你必须更喜欢,合成而不是继承。该构图避免使用fragile base class problem。
与方法调用不同,继承违反了封装
子类依赖于它们的超类,它们可能会被更改,因此子类中的功能会被破坏
使用组合和转发而不是继承,尤其是在存在实现包装类的适当接口时。
当class设计用于继承时使用继承
我建议你阅读Joshua bloch撰写的“有效Java”一书中的第16项“赞成合成而非继承”