1

我正在尝试用 Java 编写一个屏幕管理器——一种我不熟悉的语言。这个类(ScreenManager)应该能够接受一个类类型,然后实例化它。用代码更容易解​​释,所以我希望能够做到这一点:

ScreenManager manager = new ScreenManager();
manager.setCurrentScreen(MenuScreen.class);
manager.runScreen();

MenuScreen 扩展了一个名为 Screen 的类,它扩展了 JFrame。我的想法是让 AScreen、BScreen、CScreen 等都扩展 Screen,这样我就可以将它们投射到 Screen 并将它们存储为一种类型。

所以 ScreenManager 是这样的:

import javax.swing.UIManager;

public class ScreenManager {

    private Class<Screen> _currentScreen;
    private Screen _currentScreenObject;

    public ScreenManager() { }

    public ScreenManager(Class<Screen> screen) {
        setCurrentScreen(screen);       
    }

    public Class<Screen> getCurrentScreen() {
        return _currentScreen;          
    }

    public void setCurrentScreen(Class<Screen> screen) {
        _currentScreen = screen;
    }

    public void runScreen() {
        if (_currentScreen == null) return;
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                UIManager.put("swing.boldMetal", Boolean.FALSE);                
                try {
                    _currentScreenObject = _currentScreen.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {                   
                    e.printStackTrace();
                }
            }
        });
    }
}

屏幕很简单,所有的 AScreen、BScreen 等在它们的构造函数中都有一些初始化代码。

import javax.swing.JFrame;

public class Screen extends JFrame {

    private static final long serialVersionUID = 1L;

}

我绊倒的一点是将类类型传递给 ScreenManager 类。

ScreenManager manager = new ScreenManager();
manager.setCurrentScreen(MenuScreen.class);
manager.runScreen();

现在我可以像这样投射它:

Screen s = new MenuScreen();

但我似乎无法通过类类型。我试着像这样投射它:

manager.setCurrentScreen((Screen.class)MenuScreen.class);

那是行不通的。

仅供参考,我来自 C# 背景,所以我的观点可能(并且可能)是错误的。如果是这样,请纠正我。

感谢您阅读到这里!

4

2 回答 2

4

使用Class<? extends Screen>而不是Class<Screen>. 然后它会同时接受Screen.classand MenuScreen.class,给定MenuScreenextends Screen。Java 与 C# 的泛型协变等价的排序...

于 2012-06-29T21:07:18.833 回答
1

与 C# 不同,Java 中的类型参数是仅编译时的功能,并且不是协变的。

在 Java 中 aList<Integer>不是List<Number>.

您可以通过将“屏幕的某些未知子类型”声明为Class<? extends Screen>. 这是 Java 能做的最好的事情,因为它只在运行编译器时检查类型,而不是像 C# 那样运行代码时检查类型。

于 2012-06-29T21:07:31.553 回答