Java 类层次结构和设置
因此,我正在尝试制作一个简单的RPG类文本游戏,以巩固我的一些研究成果,我想知道实现这种设置的最佳方法是: 名为Fighter>的接口由AbstractFighter>MagicFighter和StrengthFighter扩展AbstractFighter实现。(最初MagicFighter和StrengthFighter有自己的接口,具有其他独特的行为)但是 现在让人困惑的是,我希望玩家能够在这两种类型的战斗机中进行选择,然后将其存储在列表(战斗机)中。所以很明显,我得到的类型总是Fighter(必须是因为我不知道用户将选择哪个Fighter实现),我只能调用Fighter接口中的方法 我可以做的一件事是,每次我需要调用不同战斗机实现特有的方法时,都要检查玩家选择了什么,并进行向下转换。但这将意味着大量重复的代码,而且听起来很混乱=/ 另一种可能是运行检查并根据用户的选择将用户添加到列表(StengthFighter)或列表(MagicFighter),但最终这与之前的“解决方案”问题完全相同 我能想到的最后一件事是尝试和镜像Fighter的每个实现,以便每个实现总是有一个版本的每个行为。比如说 无效再生();在战斗机界面中,然后对StrengthFighter和MagicFighter执行不同的操作(魔法战斗机可能会恢复法力,力量战斗机可能会在每次使用攻击时恢复怒气()(这是另一个问题,因为魔法战斗机需要执行恢复(),这显然是公开的,但在StrengthFighter中使用它是私人的) 不管怎么说,你现在可能已经明白要点了,所以我不会再发短信了Java 类层次结构和设置,java,oop,Java,Oop,因此,我正在尝试制作一个简单的RPG类文本游戏,以巩固我的一些研究成果,我想知道实现这种设置的最佳方法是: 名为Fighter>的接口由AbstractFighter>MagicFighter和StrengthFighter扩展AbstractFighter实现。(最初MagicFighter和StrengthFighter有自己的接口,具有其他独特的行为)但是 现在让人困惑的是,我希望玩家能够在这两种类型的战斗机中进行选择,然后将其存储在列表(战斗机)中。所以很明显,我得到的类型总是Fight
归根结底,这是我实现中的一个缺陷,还是OO编程不可避免?我的意思是,归根结底,Java如何知道结果需要什么类型(并因此使用它的方法)如果它要求用户做出决定以确定类型。这是一个基于对您的问题的解释的粗糙类实现。您最初定义的是一个接口,然后是一个实现,然后是单个类型,这感觉很复杂。相反,我们希望使用单个
战斗机
s,而不是r他们的代表
class Fighter {
int hp;
void attack() {
}
void move() {
}
void regen() {
hp++;
}
}
class MagicFighter extends Fighter {
int mana;
@Override
void regen() {
mana++;
//we don't regen hp because we're magic-type.
}
}
class StrengthFighter extends Fighter {
int rage;
@Override
void attack() {
super.attack();
specialRegen();
}
void specialRegen() {
rage++;
}
@Override
void regen() {
// does nothing
}
void berserk() {
rage--;
}
}
在这种情况下,我们可以存储战斗机的列表
List<Fighter> fighters = new List<>();
然后,我们将正常调用所有方法。这两个类之间共享的任何方法都不会被重写,例如Fighter.move
。对于一种类型无效的任何方法都会被重写,例如StrengthFighter.regen
。对于特定类型具有特殊附加功能的任何方法都将实现addit然后打一个super
电话,比如StrengthFighter.attack
基本上,您已经有了正确的想法,但基本上,您希望战斗机
尽可能多地执行共享工作,然后根据幕后的类型执行单独的操作。如果需要检查某个类型,则它需要是该类型战斗机特有的,例如StrengthFighter.berserk
这就减少了检查类型的需要,除非它们真的很重要。我认为你有唯一的战斗机>FighterImpl。其他人员应该单独执行:武器、装甲、能力等 在创造时,你授予战士能力+武器(受能力限制)+额外津贴。然后所有战士生活在相同的条件下
interface Fighter {
int getSpeed(); // base fighter speed per time unit
Armor getArmor();
Weapon getWeapon();
Damage attack(Fighter enemy); // animate + apply damage
Position move();
List<Perks> getPerks();
List<Ability> getAbilities();
}
interface Weapon {
DamageType getDamageType();
int getDamage();
void animateHit(Fighter enemy);
}
abstract class AbstractWeapon implements Weapon {
...
}
abstract class MeleeWeapon extends AbstractWeapon {
...
}
abstract class MagicWeapon extends AbstractWeapon {
...
}
接口战斗机{
int getSpeed();//每时间单位的基本战斗机速度
防弹衣();
武器获取武器();
伤害攻击(战斗机敌人);//动画+施加伤害
位置移动();
列出getPerks();
列出getAbilities();
}
接口武器{
DamageType getDamageType();
int getDamage();
敌方战斗机;
}
抽象类AbstractWearm实现武器{
...
}
抽象类MeleeWearm扩展了AbstractWearm{
...
}
抽象类MagicWeapon扩展了AbstractAnswarm{
...
}
让Fighter拥有一个公共类,该类的功能类似于样板文件Fighter,并扩展/覆盖MagicFighter和StrengthFighter特定的方法。另一种选择是只创建一个Fighter类,根据枚举类型处理所有事情。OO很好,但当它变得像您所展示的那样混乱时,请删除一些复杂性并保持简单。当用户选择其类型时,只需调用new MagicFighter(),然后它就会自然地调用特定方法?嘿,谢谢你花时间查看我的问题并提供答案。因此,最终调用berserk()例如,我需要沮丧,但只有在真正需要的时候?@FinalFind yes。如果一个普通的战斗机不知道狂暴,你就不能真的调用它。当然,你也可以编写一个名为特殊性的方法,但问题是你不知道这个特殊能力是否适用,所以最后,隐藏了一个事实你想叫狂暴帮不了忙。
interface Fighter {
int getSpeed(); // base fighter speed per time unit
Armor getArmor();
Weapon getWeapon();
Damage attack(Fighter enemy); // animate + apply damage
Position move();
List<Perks> getPerks();
List<Ability> getAbilities();
}
interface Weapon {
DamageType getDamageType();
int getDamage();
void animateHit(Fighter enemy);
}
abstract class AbstractWeapon implements Weapon {
...
}
abstract class MeleeWeapon extends AbstractWeapon {
...
}
abstract class MagicWeapon extends AbstractWeapon {
...
}