2013-02-24 53 views
2

我有点困惑。我有类animal,假设它存储位置等基本的东西。那么我有一个类smartAnimal,延伸animal。假设smartAnimal增加了一些功能,可以在没有用户输入的情况下做出决定。Java中正确的继承体系结构

现在,我有一个类dog,延伸animal。它不延伸smartAnimal,因为它不需要该功能。到目前为止,我很好:doganimalsmartAnimalanimal。但现在我想要smartDog延伸smartAnimalsmartDog也应该是dog。例如,很多常规dog中的功能,比如说.sniff().poop().bark()也应该在我的smartDog中,但除非我直接复制粘贴代码,否则它不会被执行,因为Java不允许多重继承。

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

class smartDog{ smartAnimal thisSmartAnimal; dog thisDog; }

...我会在animal被复制的 “东西”,比如,例如,位置。我将不得不处理两组位置变量!并在animal有任何财产的重复。

继承多个接口听起来并不像正确的解决办法,因为我们说dog是一个接口,.sniff().poop().bark()的实施不应该改变和smartDog和任何重新实现其他职业

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

编辑:

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

+1

'smartDog'应该延伸'狗' – 2013-02-24 23:44:14

+0

但是我仍然处于相同的情况,反之亦然,不得不复制+粘贴'smartAnimal'功能到'smartDog'中... – honkbert 2013-02-24 23:49:47

+1

哦,我得到了现在,在Java SE中很难,在使用Scala或IoC模式时更加简单。 – 2013-02-24 23:54:02

回答

3

答案是,这不是一个现实的继承层次结构,您可以从事实中知道您使用了“添加一些功能“来描述在子类中添加方法。这不是适当的继承。在适当的继承中(至少在Java中),每个方法应该存在于继承层次结构的顶层。继承是用于代码重用,而不是在深入树中时添加功能。因此,你所提出的问题并没有真正的答案。

+0

这是一个问题,你如何处理你的对象,以及你是否针对接口进行编程。我没有看到任何理由,为什么每个方法都只存在于层次结构层次上。 – 2013-02-24 23:58:43

+0

是的,但我看到“橙子是一种水果,但在继承方面,水果不是(必然)橙色的”例子。如果'orange'扩展了'fruit',因为'orange'具有一些特定的信息/功能来作为'orange',这不是正确的继承? – honkbert 2013-02-25 00:02:58

+0

瑞安是对的,我会推荐这个问题被关闭,因为它不是一个问题,而是一个讨论话题,可能对于这类问答论坛来说太广泛了。 – 2013-02-25 00:16:52

2

我认为你可能会寻找有一个名为“默认实现”

我认为,如果没有那个聪明的解决办法是有狗继承smartAnimal新的JDK 8功能。因此:智能狗是一种智能动物,它是一种动物。

很难有更精确的建议,因为它真的取决于您的对象正在实施。 (例如,它们全都具有内部状态吗?或者它们只是定义新的行为?)

+0

+1 **它真的取决于你的对象正在执行** – 2013-02-24 23:52:49

+0

子类对象也会有自己的内部状态。 – honkbert 2013-02-25 00:28:15

2

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

这就是说,鉴于这些例子,正确的抽象级别是适当的。 也就是说,答案就在于组合:

  1. 适当的继承(见GOF书的“是”,“有”和行为)。 如果你发现自己说“狗是聪明的” - 这可能是狗的行为,而“狗是妈妈”(注意名词与形容词)。一只“聪明”的狗表现出某些与笨笨狗不同的行为,但从数据建模的角度来看这两种狗都是“狗”。
  2. 正确的聚合。 很多时候,我发现将复杂的“事物”分解为它们的组成部分很有用。因此,“汽车”由发动机,变速箱,底盘等组成。狗有皮毛(有颜色,质地等),腿,头部,身体形状等,可能适合区分这种方式时分离狗是什么与它是如何(智能=接口)。
  3. 抽象接口。 在这个例子中可能会遇到的挑战是,不同类型的对象/名词之间的“智能”可能会有所不同。一个“聪明”狗可能能够理解命令,而“智能”手机具有某些功能,如电子邮件。因此,“智能”可能不是最高级别的适当界面,但可能与“哺乳动物”有关 - >作为哺乳动物的“狗”可能实施Mammal.Smart界面(特定于哺乳动物)。

这确实是信息建模和计算机科学整体上更困难和最重要的方面之一。整个团队的书籍和研究都专注于这一主题,因此可能不适合作为堆栈溢出问题,旨在为直接简明的问题提供简单明了的答案。