0

重複の可能性:
Javaメソッドのオーバーロード+ダブルディスパッチ

おそらくばかげた初心者の質問:。次のような状況では、instanceof演算子を避けたいと思います。

class Service {
  method(Some param) {  }
}

class Special extends Some { }

class SpecialService extends Service {
  method(Some param) {
    if (param instanceof Special) {
      //do special things 
    }
  }

  method(Special param) {
    //do special things 
  }

}

2番目の特別な方法はinstanceofを回避する正しい方法ですか?

サービスの発信者側に問題はありますか?私の場合、特別なサービスはカスタマイズされたバージョンであり、プラグインされ、ベースコードから呼び出されます。どのメソッドが呼び出されますか?

Service s = new SpecialService();
s.method(specialparam);

そして、これを解決する方法の簡潔な説明またはパターンを教えてください。基本的なJava/OOの知識のようです...

4

2 に答える 2

0

Javaはこれを自動的に行います。コードは、ifステートメントがなくても、希望どおりに機能します。Javaは、実行するメソッドのバージョンを選択するときに、最も具体的な(最もサブクラス化された)メソッドシグネチャを選択します。

これはこのテーマに関する本当に良い記事です。

于 2012-12-07T16:38:39.123 に答える
0

durron597が正しいかどうかはわかりません。それはすべて、コードの記述方法によって異なります。両方の変数が特定の型を使用して宣言されている場合にのみ、自動的に機能します。

//good
Special specialparam = new Special();
SpecialService s = new SpecialService();
s.method(specialparam);

コードのような

//bad
Some specialparam = new Special();
SpecialService s = new SpecialService();
s.method(specialparam);

または好き

//bad
Special specialparam = new Special();
Service s = new SpecialService();
s.method(specialparam);

メソッドの選択に既知のコンパイル時の型が使用されるため、期待どおりに動作しません。

全体のデザインが怪しく見えます。これは正しい方法かもしれませんが、おそらく再考する価値があります。

役立つ可能性のあるものの1つは、 dasblinkenlightのコメントで言及されているダブルディスパッチです。しかし、基本クラス (または) のいずれかを実行するには、特殊なケースについて知っておく必要があります。簡単に言えば、次のようなものを書くことです。SomeService

class Some {
  public void dispatch(Service service)  {
    service.method(this);
  }
}

class Special extends Some { 
  public void dispatch(Service service)  {
    service.method(this);
  }
}



class Service {
  void dispatch(Some some) {
      some.dispatch(this);
  }


  void method(Some some) {
     // do common things here  
  }

  void method(Special some) {
     method((Some)some);
  }
}

class SpecialService extends Service {

  method(Special param) {
    //do special things 
  }
}
于 2012-12-07T18:25:09.523 に答える