Java中的正确继承体系结构

时间:2013-02-24 23:42:49

标签: java inheritance design-principles

我有点陷入困境。我有课animal,让我们说它存储基本的东西,比如位置等等。那么我有一个smartAnimal的课程,它扩展了animal。假设smartAnimal增加了一些能够在没有用户输入的情况下做出决定的功能。

现在,我有一个扩展dog的课程animal。它不会扩展smartAnimal,因为它不需要该功能。到目前为止我很好:doganimalsmartAnimalanimal。但现在我希望smartDog 扩展smartAnimal,但smartDog也应该是dog。例如,常规dog中的许多功能,例如.sniff().poop().bark()也应该在我的smartDog但是它赢了“除非我真的复制+粘贴代码,因为Java不允许多重继承。

组成似乎不优雅,因为如果我有:

class smartDog{ smartAnimal thisSmartAnimal; dog thisDog; }

......我会复制animal中的“东西”,例如位置。我将不得不处理两组位置变量!并重复animal中的任何属性。

继承多个接口听起来也不是正确的解决方案,因为我们说dog是一个接口,.sniff().poop().bark()的实现< em>不应该为smartDog以及其他任何类而改变和重新实现。

这里的最佳做法是什么?也就是说,同时拥有dogsmartDog两个类?

编辑:

从一些评论/答案中,让我澄清一下。在我的具体项目中,smartAnimal实际上有一个控制它的整个神经网络。这是很多代码,将它抽象到接口是没有意义的。 NN功能的核心是相同的,无论动物有什么,但每个smartAnimal子类将以不同方式实现AI“大脑”的输出。相反,每个动物都拥有自己的功能,无论人类控制它还是它自己的AI代理控制它,它都会运行相同的功能。

3 个答案:

答案 0 :(得分:3)

答案是,这不是一个真实的继承层次结构,你可以从你使用的单词&#34;添加一些功能&#34;描述在子类中添加方法。这不是正确的继承。在适当的继承中(至少在Java中),每个方法都应该存在于继承层次结构的顶层。继承用于代码重用,而不是在深入到树中时添加功能。因此,对你提出的问题并没有真正的答案。

答案 1 :(得分:2)

我认为您可能正在寻找的是新的JDK 8功能,称为“默认实现”

我认为没有它的明智的解决方案是让狗继承smartAnimal。 因此:smartDog是一只狗,它是一个动物的smartAnimal。

很难得到更精确的建议,因为它实际上取决于您的对象实现的内容。 (他们都有内部状态吗?或者他们只是定义新的行为?)

答案 2 :(得分:2)

由于我们在这里谈论Java,该模型是具有多个接口的单继承。

话虽如此,给出这些例子,正确的抽象级别是恰当的。 也就是说,答案在于:

  1. 正确的继承(参见GOF书中的“是一个”,“有一个”和行为)。 如果你发现自己说“狗是聪明的” - 这可能是狗的行为而不是“狗是母亲”(注意名词与形容词)。 “智能”狗表现出某些与愚蠢狗不同的行为,但从数据建模的角度来看,它们都是“狗”。
  2. 正确聚合。 很多时候,我发现将复杂的“事物”分解为它们的组成部分是有用的。因此,“汽车”由发动机,变速箱,底盘等组成。狗有毛皮(有颜色,纹理等),腿,头,身体形状等,当这种方式区分时可能是适当的。分离狗IS与它如何行为(智能=接口)。
  3. 抽象接口。 在这个例子中可能具有挑战性的是,“聪明”在不同类型的对象/名词之间可能会有所不同。 “智能”狗可能能够理解命令,而“智能”手机具有某些功能,如电子邮件。因此,“智能”可能不是最高级别的适当界面,但可能与“哺乳动物”相关联 - &gt;作为哺乳动物的“狗”可能会实施Mammal.Smart界面(专门针对哺乳动物)。
  4. 这确实是信息建模和计算机科学整体中较为困难和重要的方面之一。整本书籍和研究小组都专注于这一主题,因此可能不适合作为Stack Overflow问题,旨在为直接简明的问题提供直接,简单的答案。

相关问题