我总是得到一个非常直接的回答"如果要生成的孩子是父母的子类型,请使用继承。"这在我做小项目时起作用,但是当我开始研究2D游戏引擎时,我遇到了相互矛盾的情况。
假设我有一个基类GameObject,为了参数,它有50个函数和5个成员变量。这些函数包括setter,getters,动画函数,渲染,移动等。它是我的玩家和敌人的完美基础。
但我也有像物品和道具这样的对象,只需要(我只希望能够访问)10个从GameObject继承的函数。我的项目仍然可以定义为GameObject,但它不会移动或有任何动画。
这里做什么?我是否继承并忽略额外的功能,创造浪费的内存? 我是否会重写这10个功能,浪费时间? 我是否将GameObject作为Item和Prop的私有成员变量,再次浪费内存但允许我阻止访问任何不需要的函数? 或者我从GameObject中删除所需的10个函数并将它们粘贴在一个单独的标题中,创建一个辅助函数库?
修改
感谢您的回复。几乎每个人都说将GameObject类拆分为更好定义的基类或使用组合。
答案 0 :(得分:7)
您希望更多地细分功能
让GameObject只包含游戏对象意味着什么的基础知识。在您的情况下,这可能是10个关键功能。 有物品,道具等直接延伸。 有另一个类,比如Character,它继承了GameObject,并且拥有Enemy和Player都使用的其他40个函数。然后玩家和敌人继承角色
答案 1 :(得分:3)
需要非常谨慎地使用继承。并记住这条规则 - 总是喜欢构成而不是继承。这不仅可以简化您的代码,还可以使其更加灵活和可单元测试。您的Game类不应该作为您的Player类的基类。但是,它可能包含一个Player对象或它们的向量。
请记住,您必须将其功能分开。游戏类不应该非常了解Player类。它应该只知道它的公共接口。因此,这里出现了接口的概念。而不是包含一个Player对象的向量,最好包含IPlayer接口的向量。然后,类Player将实现IPlayer接口。这很方便,因为在将来你可能想要引入一种新类型的玩家,因为你不必修改你的游戏类,你也不必修改你的玩家类,但你会有新的说法例如SuperPlayer类,它将再次实现IPlayer接口。
在线有大量关于此主题的文档。但这里至少有两条经验法则:1)尽可能使用接口,2)首选组合而不是继承。
希望这有用。
答案 2 :(得分:0)
你可能想要考虑别的东西而不是直接继承。
你有没有看过Entity Systems?
它们通常是将对象分成您想要的对象的好方法(它们确实需要相当多的继承,但需要更多分割)。
所以,例如,而不是具有严格的GameObject层次结构 - >实体 - > GroundEntity - > PlayerEntity,或其他东西,你可能会有类似的东西。
PlayerEntity有组件:接地,可移动,健康等。
答案 3 :(得分:0)
一个类应该代表一个抽象,并且应该具有凝聚力,这意味着它更专注于表示一种类型的实体或执行相同类型的操作。
GameObject
听起来过于抽象,你甚至可能想要删除抽象,除非游戏中的所有对象都可以被视为游戏对象。如果它们可以被视为GameObjects,那么GameObject应该具有游戏中所有对象都可以做到的绝对最小值。如果没有,请删除抽象。
从你提到的内容来看,似乎你想要的操作继承"来自GameObject的实际上可以属于Utility
类。 Utility类将具有static个方法,可以由需要类似操作的任何其他类使用。