java - 关于对象设计的澄清

标签 java oop

我有一个疑问,在面向对象设计中什么时候适合使用接口(interface),什么时候适合使用继承。假设我有一个人类类,它继承自哺乳动物类。 Mammal 类将具有实例变量,例如眼睛、 Nose 、耳朵和四肢。我的问题是 eat 方法是否应该放在 Mammal 类中,或者应该放在 Interface 中。我认为吃饭、 sleep 、呼吸方法应该放在接口(interface)内部。请告诉我我的面向对象设计是否正确,如果我的理解错误,请告诉我推理。

最佳答案

My question is whether the eat method should go inside the Mammal class or it should be in an Interface.

为什么它不能同时出现在接口(interface)基类中?

(请注意,我并不是 100% 的 Java 机制专家,并且不确定它如何在代码中实现。这是一个关于面向对象设计的与语言无关的答案。)

<小时/>

接口(interface)和基类不是可以互换的东西,正如你的问题的措辞似乎几乎暗示的那样。它们有两个截然不同的目的。

接口(interface)是一种功能契约。它是可由对象实现的一组操作。另一方面,基类是该对象的具体类型。以模糊的伪类比来思考它......

An interface tells you what something can do. A base type tells you what something is.

考虑你的例子......哺乳动物和人类。现在,很明显,哺乳动物一定是一个抽象类型。世界上不可能有一种通用的“哺乳动物”,它必须是某种物种。并考虑所有哺乳动物都以某种方式进食。

所有哺乳动物的饮食方式都完全相同吗?如果是这样,那么您可以在抽象基类上创建 eat() 的单个实现,并且所有继承类型都会使用它。

大多数哺乳动物的饮食方式完全相同,但也有一些异常(exception)?如果是这样,那么您仍然可以创建 eat() 的基本实现,但允许继承如果他们选择这样做,则可以在自己的实现中覆盖它。

大多数或所有哺乳动物都以完全不同的方式进食,但都以某种方式进食吗?如果是这样,那么您可能想要创建一个抽象的饮食() 基类中的方法签名,并要求继承类型实现它。

<小时/>

好的,那么接口(interface)从哪里来呢?

嗯,哺乳动物并不是唯一吃东西的动物。鸟儿吃东西。蜥蜴吃东西。植物吃。机器人吃饭。火食。等等

吃的东西很多。不仅仅是哺乳动物及其后代类型。甚至不仅仅是他们的祖先类型。甚至不仅仅是与哺乳动物有远亲关系的类型。 (例如,火。)因此,“吃”的概念与哺乳动物遗传中的类型层次结构正交。

为了将这些不通过继承模型相关(或者至少保证)的实现组合在一起,您需要定义一个接口(interface)。

假设您有一个操作只是想提供一个对象。虽然系统的其他部分可能关心该对象是否是哺乳动物,或任何种类的动物,甚至只是任何种类的生物……但该操作则不然。它只关心该物体可以以某种方式吃东西。机器人、火或其他一些非生物可以满足这个要求。此操作将声明它需要一个 Eater,而不是 Mammal

因此,在基本类型(生物、动物、哺乳动物等)的抽象层次结构中的某个位置,其中一种类型(可能是本例中的顶级类型)声明它实现了一个 Eater > 界面。这将强制所有继承类型也必须实现该接口(interface)。

如果存在由后代类型继承的抽象高级实现,则满足该接口(interface)。如果没有,则后代类型需要提供 eat() 的实现来满足该接口(interface)。

但重点是,完全在这个特定继承图之外的其他事物也可以实现该接口(interface)并且也可以使用。

关于java - 关于对象设计的澄清,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33200393/

相关文章:

java - 我想将最后三位设置为零,但我不知道我的代码错在哪里?

java - 在 jxta 中查找加载的模块/服务

java - Swing重复重画JComboBox闪烁

java - 如何在清除按钮上清除(空/无值)微调器

cocoa - 简化复杂的 Cocoa-Touch View Controller

php - 如何检查一个类是否属于某个命名空间

java - 用于添加功能的继承

java - 应为数组类型 [编译错误]

ruby - Ruby 中 nil 的定义在哪里

c# - 更优雅的更新空对象属性的方法