2010-11-18 8 views
-1

は、次のコードをしてみましょう:タイプに応じてメソッドを呼び出す方法は一般的ですか?

public abstract class MySuperClass { 
     public abstract void update(); 
     /* ... */ 
    } 

    public class A extends MySuperClass { 
     @Override 
     public void update() { /* ... */ } 
     /* ... */ 
    } 

    public class B extends MySuperClass { 
     @Override 
     public void update() { /* ... */ } 
     /* ... */ 
    } 

    public class Ticket<T extends MySuperClass> { 
     private Class<T> c; 
     public Ticket(Class<T> c){ this.c = c; } 
     public Class<T> getClass() { return this.c; } 
     public void update() { /* HOW TO DO! */ } 
     /* ... */ 
    } 

    public class Main { 
     public static void main(String[] args) { 
     Ticket<A> myTicket1 = new Ticket<A>(A.class); 
     Ticket<B> myTicket2 = new Ticket<B>(B.class); 
     myTicket1.update(); 
     myTicket2.update(); 
     } 
    } 

どのように私は彼のタイプに応じてチケット(AB)、またはアップグレードできますか?

+1

メタル/ウッド/カーのアナロジーがもう嫌いでしたか? ;) – aioobe

+0

いいえ、それは少し違いです – barroco

+0

私は参照された他の質問を見て、aioobeが正しいです。どちらの場合も、継承の概念のいくつかが欠落しているようです。私が必要とするのは、 'MySuperClass'オブジェクトにアクセスすることだけです。それが 'A'か' B'かどうかは関係ありません。Javaは 'update()'の実装が使用するものです。 – unholysampler

答えて

4

Ticketは実際に何が更新されているかについて何か知っているのはなぜですか?呼び出しをMySuperClassのインスタンスに転送するだけです。ジェネリッククラスの全体のポイントは、ジェネリッククラスがどのような種類であるかを正確に知ることなく、オブジェクト(またはオブジェクトのサブセット)で動作することです。

public class Ticket<T extends MySuperClass> { 
    private T thing; 
    public Ticket(T thing) { 
    this.thing = thing; 
    } 
    public void update() { 
    thing.update(); 
    } 
    /* ... */ 
} 
0

update()はインスタンスメソッドなので、インスタンスを呼び出す必要があります。これが原因polymorhismに

getClass().newInstance().update(); 

で達成することができ、それはより多くのオブジェクト指向の方法でそれを解決するのではなく、AまたはB から正しいメソッドを呼び出します、あなたはチケットのコンストラクタにインスタンスを渡すだけ必要がありますupdate()を呼び出します。

0

あなたの例を調整してより意味をなさせるようにしました。updateを実装しました。

public class Ticket<T extends MySuperClass> { 
    private Class<T> c; 
    private T t; 

    public Ticket(Class<T> c) throws InstantiationException, IllegalAccessException { 
     this.c = c; 
     this.t = c.newInstance(); 
    } 

    public Class<T> getClass() { 
     return this.c; 
    } 

    public void update() { 
     t.update(); 
    } 
    /* ... */ 
} 

update方法は、多形tが参照する実際のオブジェクトのupdate方法に派遣するt.update()を呼び出します。ここでは、Class<T>のインスタンスを作成して保存するコードを追加しました。

更新 - Ticketコンストラクタに例外を追加しました。これは、newを使用してそれらを作成し、それらを引数として渡すのではなく、リフレクションを使用してインスタンスを作成するために支払う代金の一部です。

+0

反射を使用できますか? – barroco

+0

できます。実際、あなたの例に私の微妙な調整があります。 'c.newInstance()'を参照してください。しかし、 't.update()'を呼び出すためにリフレクションを使う必要はありません。 –

関連する問題