【问题标题】:Several Constructors in JavaJava中的几个构造函数
【发布时间】:2017-04-06 16:23:23
【问题描述】:

我正在使用 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 新手。

【问题讨论】:

  • 你的构造函数是一行。你怎么可能希望它更短?
  • 每个函数都有一个独立的、完全不相关的变量。你想要类中的一个字段。
  • 你甚至没有一个真正的有任何参数的构造函数。您希望它如何更短?
  • 你的类中只有一个构造函数,其他的都是私有方法。

标签: java constructor bluej


【解决方案1】:

在您的代码中,bedRoom 是一个 局部变量 而不是属性,因此您需要在声明它时为其赋值。目前,它尚未初始化,甚至无法编译,因为如果编译了,它会在您的代码执行后立即引发 NullPointerException

如果你想在构造函数内部初始化变量,以便在任何地方都能看到它们,请将它们在外部声明为属性:

public class Game {
    Room bedRoom;
    Room kitchen;
}

并从其他方法中删除这些行:

Room bedRoom, kitchen;

【讨论】:

  • 否;它未初始化,会出现编译器错误。
【解决方案2】:

构造函数应该为每个final 成员变量设置值(在声明时不直接初始化)。所以你想要的都是不可能的。

您可以从某些成员变量中删除final 关键字,但它们可能是null,这是一个经常出现的问题。

如果你的问题是构造函数有很多参数,有(至少)两种常见的方法:

  1. 划分班级的职责。
    很可能您的课程做了很多事情,您可以将一些代码放在单独的类中。很有可能你最终会得到一堆你按顺序使用的类,这样每个类的参数就很少。

  2. 使用 Builder 模式
    使用 builder 模式,您可以创建一个单独的 Builder 类,其中每个构造函数参数都有一个单独的 setter 方法。 这些 setter 方法通常返回 this(当前的 Builder 实例),以便可以链接调用。像这样

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

    build() 方法检查是否所有属性都已给出,然后使用大量参数调用构造函数。

【讨论】:

    【解决方案3】:

    变量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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      • 2015-02-22
      • 1970-01-01
      相关资源
      最近更新 更多