我使用BlueJ为java中的学校项目编写游戏(在非常基础的层面上),并且我试图将包含大量信息的一个构造函数拆分为两个或三个单独的构造函数。在我的更改之前,初始代码如下所示:
public class Game
//fields omitted..
{
public Game() //initialise game
{
createRooms();
}
private void createRooms() // initialise rooms and exists and set start room.
{
Room bedRoom, kitchen;
bedRoom = new Room("in the bedroom");
kitchen = new Room("in the kitchen");
bedRoom.setExit("north", kitchen);
kitchen.setExit("south", bedRoom);
player = new Player(kitchen);
}
//Now, I want to seperate the contructor initialising the exits from the rest.
//I do so, by copying this to a new constructor below the createRooms constructor:
//initial code omitted..
private void createRooms() // initialise rooms
{
Room bedRoom, kitchen;
bedRoom = new Room("in the bedroom");
kitchen = new Room("in the kitchen");
}
private void createExits() // initialise room exits and set start room.
{
Room bedRoom, kitchen;
bedRoom.setExit("north", kitchen);
kitchen.setExit("south", bedRoom);
player = new Player(kitchen);
}
}
当我编译时,我在新构造函数中收到错误消息:"变量bedRoom可能尚未初始化"。我没有得到这个,因为变量是在前一个构造函数中初始化的。这可以通过上面提供的信息和代码解决吗?提前谢谢!
BR 新手。
答案 0 :(得分:1)
在您的代码中,bedRoom
是本地变量而不是属性,因此您需要在声明它时为其指定值。目前,它是未初始化的,甚至不会编译,因为如果确实如此,只要代码执行就会引发NullPointerException
。
如果你想在构造函数中初始化变量,以便随处可见它们,将它们在外面声明为属性:
public class Game {
Room bedRoom;
Room kitchen;
}
从其他方法中删除这些行:
Room bedRoom, kitchen;
答案 1 :(得分:1)
构造函数应该为每个final
成员变量设置值(在声明时不直接初始化)。所以你想要的是不可能的。
您可以从某些成员变量中删除final
关键字,但它们可能是null
,这是一个经常出现的问题。
如果问题在于构造函数有很多参数,那么(至少)有两种常用方法:
分担你班级的责任 很可能你的课程做得很多,你可以将一些代码放在单独的类中。很有可能你会最终得到一堆你按顺序使用的类,所以每个类都只有很少的参数。
使用 Builder Pattern
使用构建器模式,您可以创建一个单独的Builder类,其中每个构造函数参数都有一个单独的 setter 方法。
这些setter方法通常返回this
(当前的Builder实例),以便可以链接调用。像这样
MyClass theObject = new MyClassBuilder().withA("the A").withB("the B") /*... */ .withZ("the Z").build();
方法build()
检查是否给出了所有属性,然后使用大量参数调用构造函数。
答案 2 :(得分:0)
变量bedRoom
和kitchen
具有局部范围,它们不存在于方法之外。您应该将它们声明为类成员。还有player
。
现在,当您将类成员初始化代码放入私有方法时,您应该三思而后行。为什么?因为该方法可以在构造之后调用,并且它将重置您的成员变量!我能想到的唯一原因是你有很多成员变量,构造函数变得非常长。
class Game {
private Room bedRoom;
private Room kitchen;
private Player player;
public Game() {
// And you should initialize class members directly in the
// constructor. Most of the time.
bedRoom = new Room("in the bedroom");
kitchen = new Room("in the kitchen");
player = new Player(kitchen);
connectRooms();
}
private void connectRooms() {
bedRoom.setExit("north", kitchen);
kitchen.setExit("south", bedRoom);
}
}