如果怪物非常相似,唯一的区别是(例如)他们的名字,他们给予多少伤害,他们是什么颜色等等,那么这些差异可以反映在一个领域(在值中),可能不需要子分类。
但是,如果你的怪物与其他怪物有着根本的不同,那么就必须有非常不同的方法和逻辑,更具体地说,无法反映在字段,那么可能需要一个子类SpecialMonster。
但同样,即使SpecialMonster 也可能不需要按单个怪物类型进行子分类,因为 它的 字段可能足以区分它们。 p>
虽然拥有一百万个特定怪物类型的子类是合法的,但当它可以简单地在新的 Monster 实例的字段中表达时,您不想处理所有重复的代码,例如
new Monster("Goob", WakeTime.NOCTURNAL, 35, new Weapon[]{sword, hammer, knittingNeedle});
new Monster("Mister Mxyzptlk", WakeTime.ANYTIME, 71, new Weapon[]{sword, mindMeld, cardboardCutter});
还有一个替代方案,你确实有很多类,但你不要将它们强加给你的用户,你也不会用它们把你的 API/JavaDoc 弄得乱七八糟。如果你的 Monster 恰好是一个抽象类
public abstract class Monster {
private final String name;
...
public Monster(String name, int default_damage, WakeTime wake_time, Weapon[] weapons) {
this.name = name;
...
}
public String getName() {
return name;
}
...
public abstract int getDamage(int hit_strength);
}
那么你可以有一个这样的怪物便利创造者:
/**
<P>Convenience functions for creating new monsters of a specific type.</P>
**/
public class NewMonsterOfType {
private NewMonsterOfType() {
throw new IllegalStateException("Do not instantiate.");
}
/**
<P>Creates a new monster that is nocturnal, has 35-default-damage, and whose weapens are: sword, hammer, knittingNeedle.</P>
**/
public static final GOOB = new GoobMonster();
/**
<P>Creates a new monster that can be awake at any time, has 71-default-damage, and whose weapens are: sword, mindMeld, cardboardCutter.</P>
**/
public static final MISTER_MXYZPTLK = new MisterMxyzptlkMonster();
}
class GoobMonster extends Monster {
public GoobMonster() {
super("Goob", WakeTime.NOCTURNAL, 35, new Weapon[]{sword, hammer, knittingNeedle});
}
public int getDamage(int hit_strength) {
return (hit_strength < 70) ? getDefaultDamage() : (getDefaultDamage() * 2);
}
}
class MisterMxyzptlkMonster extends Monster {
public GoobMonster() {
super("Mister Mxyzptlk", WakeTime.ANYTIME, 71, new Weapon[]{sword, mindMeld, cardboardCutter});
}
public int getDamage(int hit_strength) {
return (hit_strength < 160) ? getDefaultDamage() + 10 : (getDefaultDamage() * 3);
}
}
为了让这些私有(实际上是包保护的)类不会出现在您的 JavaDoc 中,您需要将其 access 设置为 protected 或 public。