使用Java[接口/抽象类]

Use of Java [Interfaces / Abstract classes]

本问题已经有最佳答案,请猛点这里访问。

最近我决定看一看Java,所以我对它还是很新的,也就是面向对象编程的方法,所以我想在学习更多东西之前先弄清楚一些东西(我想从好的实践开始不久)。

我现在正在编程一个小的二维游戏,但我认为我的问题适用于任何不平凡的项目。为了简单起见,我将提供我的游戏示例。

我有不同种类的僵尸,但它们都有相同的属性(x,y,health,attack等),所以我写了一个接口僵尸,我通过walkingzombie,runningzombie teleportingzombie等实现。这是最好的事情吗?我更喜欢抽象课吗?或者和一个超级班?(我不打算部分实现函数-因此我选择接口而不是抽象类)

我有一个类描述了主角(幸存者),因为它很大,我想写一个具有不同功能的接口,这样我就可以很容易地看到和共享它的结构。这是好的做法吗?或者只是浪费时间和空间?

我希望这个问题不会被认为是主观的,因为我认为经验丰富的程序员不会反对这种主题,因为接口/超级类/抽象类的使用遵循逻辑规则,因此不仅仅是个人的选择。


您可以将接口视为"契约"。您正在定义一组实现此接口的类必须实现的方法。

另一方面,当您有一些代码可能是您想要实现的所有子类所共有的时候,就使用抽象类。因此,您可能有一个名为shape的抽象类,它有一些公共代码,在派生类(圆、正方形等)中,您可以有特定于这些形状的代码(getArea就是一个例子)。但是,类似颜色的东西可能对所有形状都很常见,所以您可以在形状抽象类中放置一个getColor方法。

你可以把这两个想法结合起来。您可以拥有实现接口的抽象类,这将为您提供最好的两个方面。

这些概念在OO中被反复使用,因此理解它们很重要。你好像在路上很好:)

因此,如果僵尸类有一些适用于所有类型僵尸的常见行为,那么作为抽象类听起来是一个不错的候选者。如果您的游戏中有其他字符(可能是UndeadMice或其他字符),您还可以考虑创建一个接口(可能是GameCharacter接口)。然后,您的Zombie抽象类和UndeadMouse抽象类将实现GameCharacter接口。


当有疑问时,我选择遵循GOF范式。

封装变化的内容:-在自己的类中定义唯一的行为。为了引用上述示例,请在其单独的类中实现步行、跑步和远程传输的行为。这样,就实现了多态行为。

相反,**聚合什么是公共的**-使用抽象类来定义多态关联中的公共行为。我在设计对象之间的关系时使用这些原则。


是的,我认为您正朝着正确的方向前进,在抽象类上使用接口。

任何你想要制造的具体僵尸都可以拥有你想要实现的步行、跑步或传送功能的任意组合。

我认为现代编程理论尽可能不鼓励继承,因为从长远来看,它会抑制可重用性和灵活性。相反,使用接口和组合来实现灵活性,而不需要"紧密耦合"。

有一种方法可以在没有继承的情况下重用代码,您可以应用"优先组合而非继承"范式。

我认为Josh Bloch的"有效Java"(第二版)可以被认为是"当前的思维"…

http://books.google.com/books?ID= ZooIQQZQBRMC和PG= RA1-PA71&LPG= RA1-PA7&DQ= %22BLCH % 22 +22Effial+Java:+编程+语言+指南%+++&;HL= DE&SIG= RXLDLRBUVVSAVAZZQOFFTRY5E×V=ONEPGE和Q&F;F = FALSE

因此,您可以将所有行为作为独立的类来实现,然后通过实现和组合为每个僵尸实现提供自己的行为组合。

希望这有意义并有帮助…


I have different kinds of zombies, but they all have the same attributes (x, y, health,
attack etc) so i wrote an interface Zombie which i implement by WalkingZombie,
RunningZombie TeleportingZombie etc. Is this the best thing to do? Am i better of with an
abstract class? Or with a super class?

抽象类将是僵尸的超级类。在某种意义上,接口也可以是超级类(超级接口?)为了你的僵尸。

公共属性至少为公共属性建议一个抽象基类。

(I am not planning to partially implement functions - therefor my choice for an interface
instead of an abstract class)

不知道这是什么意思。

如果你有不同种类的怪物(妖精、兽人等),你可能会发现这些怪物的共同行为是想属于不同的基础类。这将建议一个接口。

我将从一个抽象的基类开始,并在编写代码时看到代码告诉您什么。

I have one class describing the main character (Survivor) and since it is pretty big i
wanted to write an interface with the different functions, so that i can easily see and
share the structure of it. Is it good practice? Or is it simply a waste of space and
time?

你的幸存者被称为玩家角色(与非玩家角色相反-游戏中通常不会攻击你的幸存者的人)。

大多数游戏将所有这些角色类型视为某种怪物,因为它们都有许多共同的属性(健康)。魔法、宝藏、武器等)

所以,这可能更像是一个接口的参数。

见:

利用遗传和多态性解决一个常见的博弈问题角色扮演游戏(RPG)的类图示例角色扮演游戏中典型角色的类层次设计


没有人同意在超级/抽象类上使用接口;)

使用接口和超级/抽象类的主要原因是启用多态性。例如,在您的例子中,屏幕上有移动的东西(播放器和僵尸等等)。为什么不让他们用同样的方法在屏幕上移动呢?可能从一个叫做"可移动"的物体或者类似的东西继承所有在屏幕上移动的东西。

如果你真的喜欢这些东西,你可能也会想看看混音。它不是Java直接支持的东西,而是为它构建的库。


我会将僵尸写为抽象类,以避免重新定义字段x、y、health等…

对于幸存者类,我只需声明public外部使用的函数。我在班上宣布公共职能。当只有一个类实现接口时,声明该接口会毫无用处地添加一个要维护的文件。避开它。


我的观点是,你最好使用抽象类"生物"作为所有类型的生物的超级类,并将其扩展到所有类型的僵尸。
您还需要一个接口。定义一个生物能做什么……比如,走路,抓爪,尖叫……
你需要一个抽象类的原因是禁用生物的实例化,你不想在不知道它是什么生物的情况下拥有一个生物,对吧?


在僵尸示例中,除非您有希望所有僵尸都执行的公共代码,否则该接口将运行良好。

假设您有一个Move方法,它使walkingzombies walk、runningzombies run等运行。但是,如果您希望"move"使任何类型的僵尸做一些常见的事情,那么该接口将强制您复制代码,因为您不能在接口中放置主体。


我认为在您的例子中,您的接口和类结构与实际情况并不一致。事实上,我相信(如果我错了就纠正我)每一个僵尸可以行走、跑步、传送等,这取决于它在哪里。

因此,您应该有一个僵尸类或接口,并有修改僵尸状态的操作。该操作可能是一个接口或抽象类,因此您可以将任何操作应用于僵尸,而不知道具体的操作是什么(例如action.perform(zobie))。

如果你有不同种类的僵尸,比如三条腿的僵尸和一个武装的僵尸,你可能想要实现不同的类来处理僵尸的事情,比如显示他们自己或者验证状态的变化(例如,一种特殊的僵尸可能不接受被远程传送)。