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 |
很简单:
1 2 3 | public void addAsteroid(){ this.list.add(new Asteroid()); } |
但是如果你想打印位置,你必须在新的小行星创建时进行,所以在构造函数中:
1 2 3 4 5 |
此外:
-
将
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) 方法以使意图更加清晰