1

我有一个名为“Canvas”的超类,我从中创建了几个子类。我想将这些子类的实例存储在字典中。所以我尝试如下设置我的代码:

public class Main {
    public static void main(String[] args) throws Exception{
        Canvas canvas = new Canvas();



        Menu menu = new Menu();
        Instructions instructions = new Instructions();
        Map<String, Canvas> screens = new HashMap<String, Canvas>();
        screens.put("menu", menu);
        screens.put("instructions", instructions);

因此,由于我要添加到字典中的内容都是 Canvas 类的子类,因此我设置了哈希表以接受该类型。这有效..在大多数情况下。但是,最大的问题是我无法访问任何子类的方法。我只能调用超类中存在的方法。

如果我尝试做类似的事情,

screens.get("menu").some_func_in_subclass();

编译器吐出“找不到符号”消息。

所以,如果我有这样的事情:

SuperClass
  |
  |
  +------------------------------------   
        |               |             |
     SubClass1     SubClass2     SubClass3

我如何将这些子类的实例存储在 HashMap 中?

4

3 回答 3

5

这就是多态性的想法——所有的子类Canvas共享相同的方法(来自Canvas超类),但是如果您向这些类添加方法,它们将不再共享。

一种方法是转换您的结果(假设您已检查该值确实是 a Menu):

((Menu)screens.get("menu")).some_func_in_subclass();

但它首先破坏了将所有东西都Map<String, Canvas>放在首位的目的。

最后,要么您需要Canvas对象,并且您不应该调用子类方法,要么您需要更具体的东西,并且可能存在设计问题。

于 2012-09-09T22:19:38.103 回答
1

您如何确定子类的类型?

如果您添加SubClass1, 和的实例,SubClass2将如何确定调用哪个特殊方法?

例如,您可以检查内容的类型:

Map<String, Canvas> map = new HashMap<String,Canvas>();
map.put("a", new SubClass1());
map.put("b", new SubClass2());

if(map.get("a") instanceof SubClass1){
  // safe to cast, we checked!
  SubClass1 inst = (SubClass1) map.get("a");
  inst.some_func_in_subclass();
}

基本上,添加东西Canvas只使Canvas方法可用。您可以向上转换为更具体的类型,但您应该小心操作,检查类型是否符合您的预期,如上所示。

于 2012-09-09T22:21:16.030 回答
1

与其使用字符串作为类型,不如考虑使用Class变量:

public class Main {
    static Map<Class, Canvas> screens = new HashMap<Class<?>, Canvas>();

    public static void main(String[] args) throws Exception {
        Menu menu = new Menu();
        Instructions instructions = new Instructions();
        screens.put(menu.getClass(), menu);
        screens.put(instructions.getClass(), instructions);
    }

    public static T getScreen<T>() {
        return (T)screens.get(T);
    }
}

然后,稍后,您可以执行以下操作:

getScreen<Menu.class>().some_func_in_subclass();

编译器会知道你的意思。

于 2012-09-09T22:35:24.030 回答