在 Java 中创建类数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27729607/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:18:03  来源:igfitidea点击:

Creating an array of classes in Java

javaarraysclassstatic

提问by Grayson Pike

Is it possible to create an array of static classes in Java? For example:

是否可以在 Java 中创建一组静态类?例如:

SceneObject[] scenes = {Loading.class, Menu.class};
// Loading and Menu extend SceneObject

We need to call static methods via the array, not instantiate them.

我们需要通过数组调用静态方法,而不是实例化它们。

EDIT:

编辑:

The following is what we are trying to accomplish. We could alternatively use many switches, but it sounds redundant to add every object to every switch in every method.

以下是我们正在努力实现的目标。我们也可以使用许多开关,但是在每个方法中将每个对象添加到每个开关听起来是多余的。

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);
}

回答by Jon Skeet

You need to differentiate between classesand objects. For example, you might have:

您需要区分类对象。例如,您可能有:

SceneObject[] scenes = { new Loading(), new Menu() };

or

或者

Class[] classes = { Loading.class, Menu.class };

It's not clear from your question which you mean, but hopefully that should satisfy either case... note that you can't have generic arrays, so with the Class[]you can't specify that each class must extend SceneObject.

从您的问题中不清楚您的意思,但希望这应该满足任何一种情况……请注意,您不能拥有通用数组,因此Class[]您无法指定每个类都必须扩展SceneObject

EDIT: Now we've got a bit more information, it sounds like you've got this:

编辑:现在我们有更多的信息,听起来你有这个:

abstract class SceneObject {}

class Menu extends SceneObject {
    static void foo() {
    }

    static void bar() {
    }
}

class Loading extends SceneObject {
    static void foo() {
    }

    static void bar() {
    }
}

The two foomethods here are completely unrelated - you can't use polymorphism to call them, because they're staticmethods. If you want to use polymorphism - i.e. call a method knowing which signature you want to call, but with an implementation that depends on the target of the call - you need instancemethods:

foo这里的两个方法是完全不相关的——你不能使用多态来调用它们,因为它们是静态方法。如果你想使用多态——即调用一个知道你想调用哪个签名的方法,但使用依赖于调用目标的实现——你需要实例方法:

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() {
    }
}

Then you can write:

然后你可以写:

SceneObject[] scenes = { new Loading(), new Menu() };

...

for (SceneObject scene : scenes) {
    scene.foo();
    scene.bar();
}

回答by Then Enok

Other than making an array of classes that extend SceneObject, we can make a container for these objects:

除了创建扩展 SceneObject 的类的数组之外,我们还可以为这些对象创建一个容器:

//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
}

This answer has the benefit of specifying multiple criteria of inheritance for example:

此答案具有指定多个继承标准的好处,例如:

public class ClassBox<T extends Fragment & FR_DbRequests.SynchListener>
//now it must implement the abstract class SyncListener and extend Fragment

But also the disadvantage of instantiating an additional object ,namely the container+variable containing the class, instead of just the variable containing the class.

但也有实例化一个额外对象的缺点,即包含类的容器+变量,而不仅仅是包含类的变量。