在 Java 中创建类数组
Creating an array of classes in Java
是否可以在 Java 中创建静态类数组?
例如:
SceneObject[] scenes = {Loading.class, Menu.class};
// Loading and Menu extend SceneObject
我们需要通过数组调用静态方法,而不是实例化它们。
编辑:
以下是我们正在努力完成的工作。我们也可以使用多个开关,但是将每个对象添加到每个方法中的每个开关听起来是多余的。
package net.bitworm.gameengine;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import net.bitworm.scenes.*;
public class SceneController {
public enum Scene{
LOADING_SCENE,
MENU,
SCENE_1
}
public static SceneObject[] scenes = {new Loading(), new Menu()};
public volatile static Scene currentScene = Scene.LOADING_SCENE;
public static void setScene(Scene newScene){
currentScene = newScene;
System.out.println("Switched to " + currentScene.toString());
}
public static void update(GameContainer container, int delta){
scenes[currentScene.ordinal()].update(container, delta);
}
public static void render(GameContainer container, Graphics g){
scenes[currentScene.ordinal()].render(container, g);
}
public static void mouseMoved(int oldx, int oldy, int newx, int newy){
scenes[currentScene.ordinal()].mouseMoved(oldx, oldy, newx, newy);
}
public static void mousePressed(int button, int x, int y){
scenes[currentScene.ordinal()].mousePressed(button, x, y);;
}
public static void mouseReleased(int button, int x, int y){
scenes[currentScene.ordinal()].mouseReleased(button, x, y);
}
public static void mouseWheelMoved(int change){
scenes[currentScene.ordinal()].mouseWheelMoved(change);
}
public static void keyPressed(int key, char c){
scenes[currentScene.ordinal()].keyPressed(key, c);
}
public static void keyReleased(int key, char c){
scenes[currentScene.ordinal()].keyReleased(key, c);
}
您需要区分 classes 和 objects。例如,您可能有:
SceneObject[] scenes = { new Loading(), new Menu() };
或
Class[] classes = { Loading.class, Menu.class };
从你的问题中不清楚你的意思,但希望这应该满足任何一种情况......请注意你不能有通用数组,所以使用 Class[]
你不能指定每个class 必须扩展 SceneObject
.
编辑:现在我们得到了更多信息,听起来你已经得到了这个:
abstract class SceneObject {}
class Menu extends SceneObject {
static void foo() {
}
static void bar() {
}
}
class Loading extends SceneObject {
static void foo() {
}
static void bar() {
}
}
这里的两个foo
方法是完全不相关的——你不能用多态来调用它们,因为它们是static方法。如果你想使用多态性——即调用一个方法,知道你想调用哪个签名,但实现取决于调用的目标——你需要 instance 方法:
abstract class SceneObject {
abstract void foo() {
}
abstract void foo() {
}
}
class Menu extends SceneObject {
@Override void foo() {
}
@Override void bar() {
}
}
class Loading extends SceneObject {
@Override void foo() {
}
@Override void bar() {
}
}
那你可以这样写:
SceneObject[] scenes = { new Loading(), new Menu() };
...
for (SceneObject scene : scenes) {
scene.foo();
scene.bar();
}
除了创建扩展 SceneObject 的 classes 数组外,我们还可以为这些对象创建一个容器:
//a container that holds only the classes of SceneObject
public class ClassBox<T extends SceneObject> {
private Class<T> theClass;
public ClassBox(Class<T> theClass) {
this.theClass = theClass;
}
public Class getTheClass() { //'getClass()' method is reserved, we use a more unique name
return theClass;
}
}
//testing classes
abstract class SceneObject {}
class Loading extends SceneObject {}
class Menu extends SceneObject {}
class noExtends1 {}
//testing
public void main() {
ClassBox[] scenes = {new ClassBox<>(Loading.class), new ClassBox<>(Menu.class)}; //these classes extend SceneObject
// ClassBox[] sceneserror = {new ClassBox<>(Loading.class), new ClassBox<>(noExtends1.class)}; //gives error because 2nd array elem is not extending, so I commented it
Log.v("custom log.v call", String.valueOf(Loading.class));
Log.v("custom log.v call", String.valueOf(Menu.class));
Log.v("custom log.v call", String.valueOf(scenes[0].getTheClass()));
Log.v("custom log.v call", String.valueOf(scenes[1].getTheClass()));
//result is:
//V/custom log.v call: class me2.iwanttobealeader.pie$Loading
//V/custom log.v call: class me2.iwanttobealeader.pie$Menu
//V/custom log.v call: class me2.iwanttobealeader.pie$Loading
//V/custom log.v call: class me2.iwanttobealeader.pie$Menu
}
这个答案的好处是指定了多个继承标准,例如:
public class ClassBox<T extends Fragment & FR_DbRequests.SynchListener>
//now it must implement the abstract class SyncListener and extend Fragment
但还有实例化附加对象的缺点,即包含 class 的容器+变量,而不仅仅是包含 class.
的变量
是否可以在 Java 中创建静态类数组? 例如:
SceneObject[] scenes = {Loading.class, Menu.class};
// Loading and Menu extend SceneObject
我们需要通过数组调用静态方法,而不是实例化它们。
编辑:
以下是我们正在努力完成的工作。我们也可以使用多个开关,但是将每个对象添加到每个方法中的每个开关听起来是多余的。
package net.bitworm.gameengine;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import net.bitworm.scenes.*;
public class SceneController {
public enum Scene{
LOADING_SCENE,
MENU,
SCENE_1
}
public static SceneObject[] scenes = {new Loading(), new Menu()};
public volatile static Scene currentScene = Scene.LOADING_SCENE;
public static void setScene(Scene newScene){
currentScene = newScene;
System.out.println("Switched to " + currentScene.toString());
}
public static void update(GameContainer container, int delta){
scenes[currentScene.ordinal()].update(container, delta);
}
public static void render(GameContainer container, Graphics g){
scenes[currentScene.ordinal()].render(container, g);
}
public static void mouseMoved(int oldx, int oldy, int newx, int newy){
scenes[currentScene.ordinal()].mouseMoved(oldx, oldy, newx, newy);
}
public static void mousePressed(int button, int x, int y){
scenes[currentScene.ordinal()].mousePressed(button, x, y);;
}
public static void mouseReleased(int button, int x, int y){
scenes[currentScene.ordinal()].mouseReleased(button, x, y);
}
public static void mouseWheelMoved(int change){
scenes[currentScene.ordinal()].mouseWheelMoved(change);
}
public static void keyPressed(int key, char c){
scenes[currentScene.ordinal()].keyPressed(key, c);
}
public static void keyReleased(int key, char c){
scenes[currentScene.ordinal()].keyReleased(key, c);
}
您需要区分 classes 和 objects。例如,您可能有:
SceneObject[] scenes = { new Loading(), new Menu() };
或
Class[] classes = { Loading.class, Menu.class };
从你的问题中不清楚你的意思,但希望这应该满足任何一种情况......请注意你不能有通用数组,所以使用 Class[]
你不能指定每个class 必须扩展 SceneObject
.
编辑:现在我们得到了更多信息,听起来你已经得到了这个:
abstract class SceneObject {}
class Menu extends SceneObject {
static void foo() {
}
static void bar() {
}
}
class Loading extends SceneObject {
static void foo() {
}
static void bar() {
}
}
这里的两个foo
方法是完全不相关的——你不能用多态来调用它们,因为它们是static方法。如果你想使用多态性——即调用一个方法,知道你想调用哪个签名,但实现取决于调用的目标——你需要 instance 方法:
abstract class SceneObject {
abstract void foo() {
}
abstract void foo() {
}
}
class Menu extends SceneObject {
@Override void foo() {
}
@Override void bar() {
}
}
class Loading extends SceneObject {
@Override void foo() {
}
@Override void bar() {
}
}
那你可以这样写:
SceneObject[] scenes = { new Loading(), new Menu() };
...
for (SceneObject scene : scenes) {
scene.foo();
scene.bar();
}
除了创建扩展 SceneObject 的 classes 数组外,我们还可以为这些对象创建一个容器:
//a container that holds only the classes of SceneObject
public class ClassBox<T extends SceneObject> {
private Class<T> theClass;
public ClassBox(Class<T> theClass) {
this.theClass = theClass;
}
public Class getTheClass() { //'getClass()' method is reserved, we use a more unique name
return theClass;
}
}
//testing classes
abstract class SceneObject {}
class Loading extends SceneObject {}
class Menu extends SceneObject {}
class noExtends1 {}
//testing
public void main() {
ClassBox[] scenes = {new ClassBox<>(Loading.class), new ClassBox<>(Menu.class)}; //these classes extend SceneObject
// ClassBox[] sceneserror = {new ClassBox<>(Loading.class), new ClassBox<>(noExtends1.class)}; //gives error because 2nd array elem is not extending, so I commented it
Log.v("custom log.v call", String.valueOf(Loading.class));
Log.v("custom log.v call", String.valueOf(Menu.class));
Log.v("custom log.v call", String.valueOf(scenes[0].getTheClass()));
Log.v("custom log.v call", String.valueOf(scenes[1].getTheClass()));
//result is:
//V/custom log.v call: class me2.iwanttobealeader.pie$Loading
//V/custom log.v call: class me2.iwanttobealeader.pie$Menu
//V/custom log.v call: class me2.iwanttobealeader.pie$Loading
//V/custom log.v call: class me2.iwanttobealeader.pie$Menu
}
这个答案的好处是指定了多个继承标准,例如:
public class ClassBox<T extends Fragment & FR_DbRequests.SynchListener>
//now it must implement the abstract class SyncListener and extend Fragment
但还有实例化附加对象的缺点,即包含 class 的容器+变量,而不仅仅是包含 class.
的变量