关于oop:Java中如何动态创建对象添加到ArrayList中

How to dynamically create Objects to add into ArrayList in Java

我目前正在使用 Java 和 Codename One 构建一个 2D Asteroid 游戏,重点关注 OOP 模式。但是,我在尝试动态创建新对象(在我的情况下,我要添加的对象是超类 GameObject)以添加到 ArrayList 时遇到了麻烦。正如您在 GameWorld.java 的 void init() 方法中看到的那样,我创建了一个包含 GameObject 类型的列表,其中包括 Asteroids、Ships、Spacestations 的子类。

程序要求类中的命令键盘输入,例如\\'a\\',然后应该将新的Asteroid(GameObject 的子类)对象添加到ArrayList 中。用户应该能够添加任意数量的 Asteroid,以分配给 ArrayList。

我的问题是:在没有像我目前在 GameWorld 类的 addAsteroid() 函数中所做的那样声明 Asteroid 类型的 AsteroidTest 变量的情况下,如何做到这一点?谢谢!

GameWorld.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.mycompany.a1;

import java.util.ArrayList; //For ArrayList Usage

public class GameWorld {

public void init() {
    ArrayList<GameObject> list = new ArrayList<GameObject>();
}
//other methods here to manipulate Game objects and data
public void addShip() {
    Ship ShipTest = new Ship();  

    list.add(ShipTest);

    System.out.println(ShipTest.getLocation());
}

public void addAsteroid(){
    Asteroid AsteroidTest = new Asteroid();

    list.add(AsteroidTest);


    System.out.println(AsteroidTest.getLocation());
}


public void addSpaceStation(){

}
}

Game.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.mycompany.a1;

import com.codename1.ui.events.ActionListener;
import com.codename1.ui.Label;
import com.codename1.ui.TextField;
import com.codename1.ui.events.ActionEvent;
import java.lang.String;
import com.codename1.ui.Form;

public class Game extends Form{
private GameWorld gw;

public Game (){
    gw  = new GameWorld();
    gw.init();
    play();

}

private void play(){

    Label myLabel=new Label("Enter a Command:"); this.addComponent(myLabel);
    final TextField myTextField=new TextField();
    this.addComponent(myTextField);
    this.show();
    myTextField.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent evt) {
            String sCommand=myTextField.getText().toString();
            myTextField.clear();
            switch (sCommand.charAt(0)){
            case 's':
                gw.addShip();
                break;
            case 'a':
                gw.addAsteroid();
                break;
            case 'b':
                gw.addSpaceStation();
                break;
            //add code to handle rest of the commands
            } //switch
        } //actionPerformed
    } //new ActionListener()
            ); //addActionListener
    } //play
  //code to enter text field and receive keyboard input
}

GameObject.java 超类。子类包括小行星、船舶、导弹、空间站

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.mycompany.a1;

public abstract class GameObject {
private double x;
private double y;

public GameObject(){
    x = 0;
    y = 0;
}

public double getX(){
    return x;
}

public void setX(double newX){
    x = newX;
}

public double getY(){
    return y;
}

public void setY(double newY){
    y = newY;
}

public String getLocation(){
    return"(" + x +"," + y +")";

 }
}

Asteroid.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 package com.mycompany.a1;

 import java.util.Random;

 public class Asteroid extends MovableObject {

 private Random rand = new Random();


 public Asteroid() {
    setX(rand.nextInt(1023) + rand.nextDouble());

    setY(rand.nextInt(767) + rand.nextDouble());// TODO Auto-generated
  constructor stub
  }

 }


很简单:

1
2
3
public void addAsteroid(){
  this.list.add(new Asteroid());
}

但是如果你想打印位置,你必须在新的小行星创建时进行,所以在构造函数中:

1
2
3
4
5
public GameObject(){
  x = 0;
  y = 0;
  System.out.println("(" + x +"," + y +")");
}

此外:

  • ArrayList<GameObject> list 声明为 List<GameObject> 以使用抽象而非特定实现
  • 在 GameWorld 类中将 List<GameObject> list 声明为私有字段
  • 考虑使用构造函数而不是 public void init()
  • 如果出现并发问题,请使用 java.util.concurrent.CopyOnWriteArrayList<E> 而不是传统的 List
  • 考虑在 GameObject 中使用第二个构造函数来处理具有初始坐标的对象的创建删除 setX 和 setY 方法引入 moveTo(double x, double y) 方法以使意图更加清晰