Java 在setter中使用switch语句
这可能是一个非常愚蠢的问题,但我想我应该试着问一下!基本上,问题是:我可以在setter中使用switch语句吗 我正在做的是:我创建了一个怪物类,它的属性有healthPoints、description、damage和type,其中type是一个枚举。在我的驱动程序中,我编写了几行代码,这些代码将根据枚举值随机生成一个怪物类型,它将使用该类型创建一个新的怪物 问题是,当我显示怪物统计数据时,它显示健康点和伤害为0,描述为空。当我尝试使用默认Monster构造函数运行程序时,它崩溃并显示NullPointerException错误 我认为错误在我的setter或构造函数中。每个设定者里面都有一个开关盒,根据随机生成的怪物类型设定一定数量的健康点、伤害和特定描述。我不确定在setter中使用switch语句是否合适,因为我以前从未真正需要这样做 这是我的一些代码。首先,我的构造函数Java 在setter中使用switch语句,java,setter,Java,Setter,这可能是一个非常愚蠢的问题,但我想我应该试着问一下!基本上,问题是:我可以在setter中使用switch语句吗 我正在做的是:我创建了一个怪物类,它的属性有healthPoints、description、damage和type,其中type是一个枚举。在我的驱动程序中,我编写了几行代码,这些代码将根据枚举值随机生成一个怪物类型,它将使用该类型创建一个新的怪物 问题是,当我显示怪物统计数据时,它显示健康点和伤害为0,描述为空。当我尝试使用默认Monster构造函数运行程序时,它崩溃并显示Nul
public Monster(int healthPoints, monsterType type, int damage, String description)
{
setHealthPoints(healthPoints);
setType(type);
setDamage(damage);
setDescription(description);
}
public Monster(monsterType type)
{
setType(type);
}
下面是一个设定者
public void setHealthPoints(int healthPoints)
{
switch(type)
{
case DROW:
healthPoints = 30;
break;
case LICH:
healthPoints = 40;
break;
case ORC:
healthPoints = 20;
break;
case OWLBEAR:
healthPoints = 20;
break;
case RUST_MONSTER:
healthPoints = 10;
break;
}
this.healthPoints = healthPoints;
}
下面是驱动程序中创建怪物的线条
int number = new Random().nextInt(monsterType.values().length);
Monster monster = new Monster(monsterType.values ()[number]);
我希望怪物的生命值、伤害和描述根据生成的怪物类型来设置。我不确定这是否可以通过设置器中的开关来实现,我觉得我的错误可能是显而易见的,我只是没有看到它,因为我已经盯着它看了很长时间……或者,如果有不同或更简单的方法来实现,请让我知道!感谢您抽出时间阅读;我试图把我的问题/问题弄清楚。解释
是的,您可以在构造函数和方法中使用开关
案例。问题是您在setType
之前调用setHealthPoints
,但第一种方法在其开关
语句中使用type
:
setHealthPoints(healthPoints);
setType(type);
因此,当您访问设置健康点
的开关时,变量类型
未初始化,因此当前为空
如果switch
语句的参数为null
,则该语句将抛出NullPointerException
。这样就得到了NPE
您可以通过首先执行setType
来解决此问题
关于游戏架构的建议
您应该创建一个更可读的结构,该结构也更易于维护,尤其易于扩展
请考虑创建一个<代码>怪物>代码>强>接口<强>或>强>抽象类< /强>。之后,创建显式怪物作为子类。类怪物
将包含所有怪物中平等的一切,尝试从特定的怪物中抽象出来。怪物本身将只包含与其他怪物不同的东西
例如,您可以使用以下类型:
public abstract class Monster {
private int mHealthPoints;
private int mDamage;
private String mDescription;
public Monster(int healthPoints, int damage, String description) {
this.mHealthPoints = healthPoints;
this.mDamage = damage;
this.mDescription = description;
}
public int getHealthPoints() {
return this.mHealthPoints;
}
public int getDamage() {
return this.mDamage;
}
public String getDescription() {
return this.mDescription;
}
}
然后你有特定的怪物类,比如
public class Orc extends Monster {
private static int HEALTH = 20;
private static int DAMAGE = 10;
private static String DESCRIPTION = "Nasty orc.";
public Orc() {
super(Orc.HEALTH, Orc.DAMAGE, Orc.DESCRIPTION);
}
}
您也不再需要怪物类型
枚举,因为您可以通过Orc的怪物实例
进行区分。然而,对于真正的模块化设计,您不应该在特定的类上工作。相反,使用大量描述属性和能力的接口
例如,接口如下:
CanAttack
IsAttackable
HasHealth
CanWalk
CanFly
CanCollide
...
您的游戏逻辑可能只建立在这些接口上。例如,CanAttack
可能看起来像:
public interface CanAttack {
void attack(IsAttackable target);
}
最大的优势是你可以轻松地扩展你的游戏。例如,通过创建具有任意能力组合的怪物:
public SuperFlyingPig extends Monster implements
CanAttack, HasHealth, CanWalk, CanFly {
...
}
它将神奇地工作,没有任何额外的编码工作,因为您的逻辑将不关心特定的怪物。它只适用于接口我认为您应该使您的结构更容易阅读。使用Monster
作为接口,然后创建显式子类,如Drow
、Lich
、Orc
、Owlbear
和RustMonster
,它们都实现了Monster
。如果你的怪物
的代码在所有这些怪物中都是相等的,那么你也可以将你的怪物
变成一个抽象类。然后,该代码转到Monster
,而其余代码转到子类。然后确定共同的结构,怪物应该只包含使他们独一无二的其他。比如一个变量maximalHealth左右。setter本身对所有人都是一样的。您的问题之一似乎是您的第一个构造函数应该在调用setHealthPoints()之前调用setType()
。后一种方法取决于(明显的)实例变量type
。请遵守命名约定。类应以大写字符开头。因此,您的enum
应该改为MonsterType
。完整的答案解释了问题以及如何解决问题,此外,还通过展示如何改进当前代码来实现。做得好。