Java 继承 -> 无法引用构造函数中的实例字段错误?



我希望c是随机颜色,这样我就可以生成许多不同颜色的敌人,但不知道该怎么做。如果我像 Color.cyan 一样放进去,它可以正常工作。但是如果我想在 super(( 中放一个变量,它不喜欢这样。我是Java的新手,所以我只是想弄清楚事情。在不使变量成为静态的情况下,这可能吗?

package first.Game;
import java.awt.Color;
import java.util.Random;
public class MenuEnemy extends Enemy{
private Random r = new Random();
private Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
public MenuEnemy(float x, float y, Handler handler)
{
super(x, y, 16, 16, 2, 8, c, ID.Enemy, handler);
}
}

问题是字段尚未初始化,因为子类非静态字段初始化是在 super 之后执行的。

这里有一些选择,2种可能性是:

  • 您可以添加一个静态方法来获取随机颜色,并在构造函数中使用它而不是c
public static Color getRandomColor() {
Random r = new Random();
return new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
}
  • 你也可以在调用 super 后定义颜色,尽管我建议不要这样做,因为如果你在超类构造函数中使用c来做一些事情,它会失败,因为我们将其设置为 null,将其设置为随机静态颜色也可能产生不必要的副作用。
super(..., null, ...);
Random r = new Random();
this.c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));

如果您使用第一个建议,这将是最终结果。

public class Enemy {
protected float x, y;
protected int i1, i2, i3, i4;
protected Color c;
protected String id;
protected Handler handler;
public Enemy(float x, float y, int i1, int i2, int i3, int i4, Color c, String id, Handler handler) {
this.x = x;
this.y = y;
this.i1 = i1;
this.i2 = i2;
this.i3 = i3;
this.i4 = i4;
this.c = c;
this.handler = handler;
}
public static Color getRandomColor() {
Random r = new Random(); // TODO possibly reuse a static random somewhere, depends on use-case
return new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
}
}
public class MenuEnemy extends Enemy {
public MenuEnemy(float x, float y, Handler handler) {
super(x, y, 16, 16, 2, 8, Enemy.getRandomColor(), ID.Enemy, handler);
}
}

可以有另一个构造函数。

package first.Game;
import java.awt.Color;
import java.util.Random;
public class MenuEnemy extends Enemy {
private Random r = new Random();
protected Color c;
public MenuEnemy(float x, float y, Handler handler)
{
this(x, y, handler, new Color((new Random()).nextInt(255), (new Random()).nextInt(255), (new Random()).nextInt(255)));
}
private MenuEnemy(float x, float y, Handler handler, Color c)
{
super(x, y, 16, 16, 2, 8, c, ID.Enemy, handler);
this.c = c;
}
}

您应该使用生成器设计模式

package first.Game;
import java.awt.Color;
import java.util.Random;
class ID {
public static final String Enemy = "e";
}
class Handler {
}
class Enemy {
public Enemy(float x, float y, int p1, int p2, int p3, int p4, Color c, String id, Handler handler) {
}
}
public class MenuEnemy extends Enemy {
private Random r = new Random();
private Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
protected MenuEnemy(Builder builder) {
super(builder.x, builder.y, 16, 16, 2, 8, builder.c, ID.Enemy, builder.handler);
}
public static class Builder {
private float x;
private float y;
private Handler handler;
private Random r = new Random();
private Color c;
public Builder x(float x) {this.x = x; return this;};
public Builder y(float y) {this.y = y; return this;};
public Builder handler(Handler handler) {this.handler = handler; return this;};
public Builder r(Random r) {this.r = r; return this;};
public Builder c(Color c) {this.c = c; return this;};
public MenuEnemy build() {
if(c == null)
c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
return new MenuEnemy(this);
}
}
public static void main(String[] args) {
MenuEnemy enemy = new Builder()
.x(10)
.y(10)
.handler(new Handler())
.r(new Random())
.build();
System.out.println(enemy);
}
}

最新更新