2016-11-22 75 views
0

我正在使用BlueJ編寫一個Java學校項目的遊戲(在一個非常基礎的層面上),我試圖將一個包含大量信息的構造函數分成兩個或三個單獨的構造函數。最初的代碼,我改變之前如下所示: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); 
    } 
} 

當我編譯,我得到了新的構造函數中的錯誤消息:「可變臥室可能沒有被初始化」。我沒有得到這個,因爲變量是在前面的構造函數中初始化的。這可以從上面提供的信息和代碼解決嗎?提前致謝!

BR 新手。

+5

您的構造函數是一行。你怎麼可能希望它更短? –

+1

你的每個函數都有一個單獨的,完全不相關的變量。你想在課堂上有一個領域。 – SLaks

+0

你甚至沒有一個真正的構造函數,它有任何參數。你想如何縮短它? – Grunzwanzling

回答

1

在您的代碼中,bedRoom局部變量不是屬性,因此當您聲明它時需要爲其指定一個值。目前,它是未初始化的,它甚至不會編譯,因爲如果它執行了,只要執行代碼就會引發NullPointerException

如果您想初始化的構造,使他們到處可以看到裏面的變量,聲明他們爲屬性:

public class Game { 
    Room bedRoom; 
    Room kitchen; 
} 

而從其他方法刪除這些行:

Room bedRoom, kitchen; 
+0

否;它是未初始化的,並且會給出編譯器錯誤。 – SLaks

+0

@SLaks對,我重新回答了我的答案。 –

1

Constructores應該爲每個final成員變量(在聲明時不直接初始化)設置值。所以你想要的是不可能的。

您可以從某些成員變量中刪除final關鍵字,但它們可能是null,這經常是個問題。

如果你的問題是,構造函數有許多參數,有(至少)2種常用的方法:

  1. 分割你的類的責任。
    你的班級很可能會做很多事情,你可以放一些代碼來分開班級。很有可能你最終會得到一系列依次使用的類,這樣每個類都只有很少的參數。

  2. 使用Builder模式
    與您共創,你必須爲每個構造函數的參數單獨二傳手方法單獨生成器類生成器模式。 這些設置方法通常會返回this(當前的Builder實例),以便可以調用鏈接。這樣

    MyClass theObject = new MyClassBuilder().withA("the A").withB("the B") /*... */ .withZ("the Z").build();

    的方法,如果所有屬性都給出build()檢查,然後調用與許多參數的構造。

0

變量bedRoomkitchen具有本地範圍,他們沒有方法之外存在。你應該將它們聲明爲類成員。還有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); 
    } 
}