Java 关于对象设计的澄清

Java 关于对象设计的澄清,java,oop,Java,Oop,我怀疑什么时候使用接口合适,什么时候在OO设计中使用继承。假设我有一个人类类,它继承自哺乳动物类。哺乳动物类将具有眼睛、鼻子、耳朵和四肢等实例变量。我的问题是eat方法是应该放在哺乳动物类中还是应该放在接口中。我认为吃、睡、呼吸的方法应该放在一个界面里面。请让我知道我的OO设计是否正确,如果我的理解是错误的,请告诉我原因。你是正确的。您可以创建一个像Animal这样的界面,该界面将包含这些方法。在子类(实现Animal)中,应该实现这些方法。因为例如哺乳动物、爬行动物都有不同的行走技术,你是对的

我怀疑什么时候使用接口合适,什么时候在OO设计中使用继承。假设我有一个人类类,它继承自哺乳动物类。哺乳动物类将具有眼睛、鼻子、耳朵和四肢等实例变量。我的问题是eat方法是应该放在哺乳动物类中还是应该放在接口中。我认为吃、睡、呼吸的方法应该放在一个界面里面。请让我知道我的OO设计是否正确,如果我的理解是错误的,请告诉我原因。

你是正确的。您可以创建一个像
Animal
这样的界面,该界面将包含这些方法。在子类(实现
Animal
)中,应该实现这些方法。因为例如哺乳动物、爬行动物都有不同的行走技术,你是对的。您可以创建一个像
Animal
这样的界面,该界面将包含这些方法。在子类(实现
Animal
)中,应该实现这些方法。因为例如哺乳动物、爬行动物都有不同的行走技术,你是对的。您可以创建一个像
Animal
这样的界面,该界面将包含这些方法。在子类(实现
Animal
)中,应该实现这些方法。因为例如哺乳动物、爬行动物都有不同的行走技术,你是对的。您可以创建一个像
Animal
这样的界面,该界面将包含这些方法。在子类(实现
Animal
)中,应该实现这些方法。因为例如哺乳动物,爬行动物有着不同的行走技术

我的问题是eat方法是应该放在哺乳动物类中还是应该放在接口中

为什么不能同时在接口和基类中

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


接口和基类是不能互换的,正如你问题的措辞所暗示的那样。它们有两个截然不同的用途

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

一个界面告诉你一些事情可以做什么。 基本类型告诉你什么是东西

考虑一下你的例子。。。哺乳动物和人类。现在,很明显,哺乳动物必须是抽象类型。你不能让一个普通的“哺乳动物”在世界上四处走动,它必须是某种物种。并认为所有哺乳动物都以某种方式吃。

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

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

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


好的,那么接口从何而来

哺乳动物不是唯一吃东西的动物。鸟吃东西。蜥蜴吃东西。植物吃东西。机器人吃东西。火吃人。等等

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

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

假设您有一个只想为对象提供信息的操作。虽然系统的其他部分可能关心该物体是否是哺乳动物,或任何种类的动物,甚至只是任何种类的生物。。。此操作不支持。它只是关心物体在某种程度上可以吃东西。机器人、火或其他非生物可以满足这一要求。此操作将声明它需要的是
食肉动物,而不是
哺乳动物

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

如果存在由子体类型继承的抽象高级实现,则满足接口。如果没有,那么子体类型将需要提供
eat()
的实现来满足接口

但关键是,完全在这个特定继承图之外的其他东西也可以实现该接口,也可以eat

我的问题是eat方法是应该放在哺乳动物类中还是应该放在接口中

为什么不能同时在接口和基类中

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


接口和基类是不能互换的,正如你问题的措辞所暗示的那样。他们提供两种非常好的服务