5

私はこの単純なインターフェース/クラスを持っています:

public abstract class Message {}

public class Message1 extends Message {}

public class Message2 extends Message {}

そしてユーティリティクラス:

public class Utility {
    public void handler(Message m) {
        System.out.println("Interface: Message");
    }

    public void handler(Message1 m) {
        System.out.println("Class: Message1");
    }

    public void handler(Message2 m) {
        System.out.println("Class: Message2");
    }
}

さて、メインクラス:

public static void main(String[] args) {

    Utility p = new Utility();

    Message1 m1 = new Message1();
    p.handler(m1);

    Message m = (Message) m1;
    p.handler(m);

}

出力は

> Class: Message1
> Interface: Message

私はそれp.handler(m)がメソッドを呼び出すだろうp.handler(m:Message1)

instanceof多くの場合があるので、「手動」コマンドを使用したくありません。

if(m instance of Message1)
p.handler((Message1)m)
else if (m instanceof Message2)
p.handler((Message2)m)
...

呼び出すm.getClass()と、「mypackage.Message1」が取得されるため、スーパークラスではなくサブクラスが取得されます。

私はこのコードで試してみます(リフレクションを使用):

p.handler(m.getClass().cast(m));

しかし、出力は

> Interface: Message

だから、これは私の問題です。「コードコマンド」istanceofを使用せずに、スーパークラスオブジェクトからサブクラスオブジェクトへのランタイムキャストを実行します。

私はこのような正しいコマンドをします:

p.handler((m.getclass)m);

どうすれば入手できますか?それが可能だ?

4

2 に答える 2

9

Javaは、コンパイル時に既知の情報に基づいてメソッドを呼び出します。できることは、オブジェクトの正しいハンドラーメソッドを呼び出すメソッドをインターフェイスに追加することです。

public abstract class Message {

    public abstract void callHandler(Utility utility);

}

public class Message1 extends Message{

    public void callHandler(Utility utility) {
        utility.handler(this);
    }
}

ハンドラーへの呼び出しは次のようになります。

Message m=(Message) m1;
m.callHandler(p);

mainの参照がメッセージインターフェイスのタイプであるにもかかわらず、Utility :: handler(Message1)を呼び出すようになりました。

于 2010-05-06T10:55:40.853 に答える
0

handle(..)メソッドが何をするのかわかりませんが、Messageの特定のインスタンスに依存するため、messageクラスにhandle()メソッドを(抽象メソッドとして)追加することを検討する必要があります。このように、各メッセージはそのバージョンのハンドルを実装し、ポリモーフィズムの利点を享受できます。

Message m = new Message1();
m.handle();

このコードは、必要に応じて「Class:Message1」を返します。

于 2010-05-06T11:02:25.707 に答える