所以我试图制作一个简单的类似RPG的基于文本的游戏来巩固我的一些研究,我想知道实现这种类型设置的最佳方法是:
称为战斗机的界面>由AbstractFighter实现> MagicFighter和StrengthFighter扩展了AbstractFighter。 (最初MagicFighter和StrengthFighter有自己的接口以及其他独特的行为)但是......
现在让我感到困惑的是,我希望玩家能够在这两种类型的战斗机之间进行选择,然后我将其存储在一个列表(战斗机)中。显然,我得到的类型总是战斗机(它必须是因为我不知道用户将选择哪种战斗机实现)而且我只能调用战斗机界面中的方法
我能做的一件事就是每当我需要调用不同战斗机实现的独特方法时,就会检查玩家选择的内容并进行预测。但这意味着很多重复的代码,听起来很乱= /。
另一种可能性是根据他们的选择运行检查并将用户添加到List(StengthFighter)或List(MagicFighter),但最终这个问题与之前的“解决方案”完全相同。
我能想到的最后一件事是尝试镜像战斗机的每个实现,以便每个行为始终都有一个版本。所以举个例子 void regen();在战斗机界面中,然后对于StrengthFighter和MagicFighter进行不同的实施(魔术战士可能会重新获得法术力,强力战斗机可能会在每次使用攻击时重新发怒()(由于ManaFighter需要实施regen(),这显然是公共的另一个问题,但在StrengthFighter中使用它将是私人的。)
无论如何,你现在可能已经得到了要点,所以我再保存了一个文字墙。
它归结为什么;这是我实施中的一个缺陷。或者这只是OO编程的必然性?我的意思是,在一天结束时,如果要求用户做出决定类型的决定,Java如何知道结果需要什么类型(因此使用其方法)。
答案 0 :(得分:0)
这是基于您的问题解释的粗略类实现。您拥有接口然后是实现然后单个类型的原始定义感觉很复杂。相反,我们希望使用单个Fighter
而不是它们的表示。
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--;
}
}
在这种情况下,我们可以存储Fighter
List<Fighter> fighters = new List<>();
当我们想要创造一个新战斗机时,我们会确定用户想要什么并将其添加到战斗机列表中。
if (selection.equals("StrengthFighter")) {
Fighter fighter = new StrengthFighter();
fighters.add(fighter);
}
然后,我们将所有方法称为正常。两个类之间共享的任何内容都不会被覆盖,例如Fighter.move
。任何不适用于一种类型的东西都会被覆盖,例如StrengthFighter.regen
。对特定类型具有特殊附加功能的任何内容都将实现其他功能并进行super
调用,例如StrengthFighter.attack
。
基本上,你已经有了正确的想法,但基本上,你希望Fighter
尽可能多地完成共享工作,然后根据幕后的类型实现各个动作。如果需要检查某些类型的东西,则需要对该类型的战斗机具有独特的功能,例如StrengthFighter.berserk
。
这减少了检查类型的需要,除非它们真正重要。
答案 1 :(得分:0)
我认为你有唯一的战士&gt; 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 {
...
}