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 クラスのサブクラスなので、その Type を受け入れるようにハッシュテーブルを設定します。そして、これは機能します..ほとんどの場合。ただし、大きな問題は、サブクラスのメソッドにアクセスできないことです。スーパークラスに存在するメソッドしか呼び出せません。

次のようなことをしようとすると、

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

コンパイラは「シンボルが見つかりません」というメッセージを吐き出します。

だから、私はこのようなものを持っている場合:

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

これらのサブクラスのインスタンスを HashMap に格納するにはどうすればよいですか?

4

3 に答える 3

5

これがポリモーフィズムの考え方です。 のすべてのサブクラスはCanvas(スーパー クラスの) 同じメソッドを共有しCanvasますが、それらのクラスにメソッドを追加すると、それらは共有されなくなります。

1 つの方法は、結果をキャストすることです (値が実際に a であることを確認したと仮定しますMenu)。

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

Map<String, Canvas>しかし、それはそもそもすべてを a に保持するという目的を無効にします。

最終的には、Canvasオブジェクトが必要であり、サブクラスのメソッドを呼び出す必要がないか、より具体的なものが必要であり、おそらく設計上の問題があるかのいずれかです。

于 2012-09-09T22:19:38.103 に答える
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 に答える
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();
}

基本的に、 as を追加すると、メソッドCanvasのみが使用可能になります。より具体的な型に上向きにキャストCanvasすることもできますが、上記のように、期待どおりの型であることを確認して慎重に行う必要があります。

于 2012-09-09T22:21:16.030 に答える