0

所以我有这个构造函数:

 public MyClass(boolean done, int lvl , String s, int x, int y, Skill parent, Item item, int cost) {
    this.done = done;
    this.lvl = lvl;
    this.name = s;
    this.Xpos = x;
    this.Ypos = y;
    this.parent = parent;
    this.item = item;
    addSkill(this, s);
}

有没有办法让我在另一个类中使用/初始化它而不必做

MyClass myclass = new MyClass(false, 0, "", 0, 0, null, this.item, 1)

如果我只是这样做

MyClass myclass;

然后我得到“可怕的”空指针异常。

4

5 回答 5

3

听起来您想创建第二个不带参数的构造函数。

然后你可以写

MyClass myclass = new MyClass();
于 2013-08-20T17:16:39.517 回答
2

我建议您实现类似于Builder Pattern的东西。它用途广泛。您可以在 Wikipedia 上阅读更多关于Builder 模式的信息。

于 2013-08-20T17:22:12.810 回答
0

MyClass myclass;只是一个参考。您需要将其与某个对象绑定。没有电视就不能使用遥控器。您可以尝试缩短构造函数的其他方法就是提供一个 0 参数构造函数。

 public MyClass() {
    this.done = "default";
    this.lvl = "default value";
    this.name = "default value";
    this.Xpos = "default value";
    this.Ypos = "default value";
    this.parent = "default value";
    this.item = "default value";
}

现在你可以这样做MyClass mcRef=new MyClass();

于 2013-08-20T17:20:55.083 回答
0

听起来您可能需要一些“默认参数”。在 Python 中,您可以执行以下操作:

class MyClass:
    def __init__(done=false, load=1, ...):
        self.done = done
        self.load = load
        # ...

a_new_instance = MyClass(done=true)

基本上,您的所有变量都以默认值开始 -如果您愿意,可以更改它们。

在 Java 中,它有点不同:

class MyClass {
    private boolean done = false; // Notice the default value for done will be false
    // ... you would list (and instantiate!) the rest of your variables

    public MyClass() {}

    public MyClass(boolean done, int lvl, ...) {
         this.done = done;
         // ...
    }
}

这样,如果您想更改默认值,您只需要调用构造函数。但是,如果您只想更改 1 或 2 个值会发生什么?好吧,您可以创建新的构造函数:

public MyClass(boolean done) { this.done = done; }
public MyClass(boolean done, int lvl) { this.done = done; this.lvl = lvl; }

但这很快就会失控!

所以,为了解决这个问题,我们可以使用“builder”模式。这看起来像这样:

public class MyClass {
    private boolean done;
    private int lvl;

    // Now the constructor is private and takes a builder.
    private MyClass(MyClassBuilder builder) {
        // ... and your variables come from the ones you will build.
        this.done = builder.done;
        this.lvl = builder.lvl;
        // ...
    }

    public static class MyClassBuilder {
        // The builder also has the same members.
        private boolean done;
        private int lvl;

        // Notice that we return the builder, this allows us to chain calls.
        public MyClassBuilder done(boolean isDone) {
            this.done = isDone;
            return this;
        }   

        public MyClassBuilder level(int level) {
            this.lvl = level;
        }

        // And a method to build the object.
        public MyClass build() {
            MyClass mc = new MyClass();
            mc.done = this.done;
            mc.lvl = this.lvl;
            // ... copy over all your variables from the builder to the new class
            return mc;
        }
    }
}

所以,现在当我们想要实例化一个MyClass对象时,我们可以这样做:

MyClass mc = MyClassBuilder.done(false);

或者,我们可以链接调用:

MyClass mc2 = MyClassBuilder.done(true).level(4). // ... you can go on for a while

顺便说一句,有时一个类中包含三个或四个以上的变量表明该类做得太多。如果班级有多个“职责”,则应将其分成几个较小的班级。那么您将不需要构建器类。

于 2013-08-20T17:37:43.390 回答
0

这不是 C++。所有引用的默认值为null. 如果不使用new,对象仍然存在null

如果您不喜欢多参数构造函数,有几种初始化方法。您可以让 setter 返回this并进行链式初始化,例如:

Person p = new Person().setAge(18).setName("Tom").setHeight(175);

甚至简单地

Person p = new Person().age(18).name("Tom").height(175);

这种方法不是很常见,但绝对易于阅读且不易出错。

您还可以使用静态工厂方法,例如

class Person {

  private Person() {} // mark as private to force  creation with static method

  public static Person create() {
    Person p = new Person();
    //fill default values?
    return p;
  }
}
于 2013-08-20T18:04:07.663 回答