您已经得到了一些不错的答案,但是您问题中房间里的那头巨大的大象就是这个:
有人听说必须避免使用继承,我们应该改用接口
根据经验,当有人给你一个经验法则时,请忽略它。这不仅适用于“有人告诉你一些事情”,还适用于阅读互联网上的内容。除非您知道为什么(并且真的可以支持它),否则此类建议毫无价值,而且通常非常有害。
以我的经验,OOP中最重要和最有用的概念是“低耦合”和“高内聚”(类/对象彼此之间的了解尽可能少,并且每个单元负责尽可能少的事情)。
低耦合
这意味着代码中的任何“一堆东西”都应尽可能少地依赖于其周围环境。这同样适用于类(类设计),而且对象(实际执行),一般的“文件”(即数#include
每个单独的S .cpp
档,数量import
每单个.java
文件等)。
两个实体已耦合的迹象是,当另一个实体以任何方式更改时,其中一个实体将损坏(或需要更改)。
显然,继承会增加耦合。更改基类将更改所有子类。
接口可减少耦合:通过定义一个清晰的,基于方法的合同,只要不更改合同,就可以自由更改接口两侧的任何内容。(请注意,“接口”是一个通用概念,Java interface
或C ++抽象类只是实现细节)。
高凝聚力
这意味着让每个类,对象,文件等都尽可能少地与之相关或负责。即,避免使用做很多事情的大类。在您的示例中,如果您的武器具有完全独立的方面(弹药,射击行为,图形表示,库存表示等),那么您可以使用不同的类来精确地代表其中的一种。然后,主要武器类别将转变为这些细节的“持有人”。那么,武器对象不过是指向这些细节的一些指针而已。
在此示例中,您将确保代表“射击行为”的班级对主要武器类的了解尽可能少。理想情况下,什么都没有。例如,这意味着您只需轻轻一按,就可以对世界上的任何物体(炮塔,火山,NPC等)进行“射击行为” 。如果您想在某个时间点更改武器在清单中的表示方式,那么您可以简单地做到这一点-只有您的清单类对此有所了解。
一个实体不具有内聚力的迹象是,它会越来越大,同时在多个方向上分支。
正如您所描述的那样,继承会降低凝聚力-归根结底,您的武器类别很多,可以处理武器的各种不同的,无关的方面。
界面通过在界面的两侧之间明确划分职责来间接增加内聚力。
现在做什么
仍然没有硬性规定,所有这些都只是指导原则。总的来说,正如用户TKK在回答中提到的那样,在学校和书籍中对继承的知识很多。这是关于OOP的幻想。接口可能更无聊,而且(如果您忽略了一些琐碎的示例)也更难一点,从而打开了依赖注入的领域,这种注入不像继承那么明确。
归根结底,基于继承的方案仍然比根本没有清晰的OOP设计要好。因此,请随时坚持。如果愿意,您可以对低耦合,高内聚性进行反思/谷歌搜索,看看是否希望将这种想法添加到您的武器库中。如果以后愿意,您可以随时重构以尝试一下。或在下一个更大的新代码模块中尝试基于接口的方法。