2012-06-29 65 views
1

我正在尝试用Java编写一个屏幕管理器 - 我是一个新手。这个类(ScreenManager)应该能够接受一个类的类型然后实例化它。它更容易使用代码来解释的话,我希望能够做到这一点:如何将Java类封装/转换为父类类型?

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

MenuScreen延伸的类称为屏幕延伸的JFrame。我的想法是让AScreen,BScreen,CScreen等都扩展屏幕,以便我可以将它们投射到屏幕并将它们存储为单一类型。

所以屏幕管理是这样的:

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 manager = new ScreenManager(); 
manager.setCurrentScreen(MenuScreen.class); 
manager.runScreen(); 

现在我可以投它像这样:

Screen s = new MenuScreen(); 

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

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

这是行不通的。我只是来自C#背景,所以我的观点可能(也可能是)错误。如果是这样,请纠正我。

感谢您的阅读!

+3

为什么不只是manager.setCurrentScreen(new MenuScreen())? – Matsemann

+0

是的,那部分也让我感到困惑。 Java在一个相对简单的应用程序中很少与实际的类相提并论,而不是该类的实例。 – Marvo

+0

我的印象是我需要用'javax.swing.SwingUtilities.invokeLater'运行,看到这个:http://stackoverflow.com/questions/6567870/what-does-swingutilities-invokelater-do –

回答

4

使用Class<? extends Screen>而不是Class<Screen>。它将接受Screen.classMenuScreen.class,给定MenuScreen延伸Screen。 Java的等价于C#的泛型协方差...

+0

令人惊叹。谢谢!我在阅读过的一些文档中看到了这一点,但没有注意到它是解决方案。 –

1

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

在Java a List<Integer>不是List<Number>

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

+0

啊我明白了。现在有道理。类<?扩展屏幕>作品。谢谢! +1 –