2

次のクラスがあるとしましょう。

public interface X {
...
}

public class A implements X {
...
}

public class B implements X {
...
}

ここで、タイプXのオブジェクトを受け取るメソッドがどこかにあり、Xの各実装を異なる方法で処理する必要があるとします。ナイーブなアプローチは次のとおりです。

public void doSomething(X x) {
  if(x instanceof A)
    doSomethingA((A) x);
  else if(x instanceof B)
    doSomethingB((B) x);
}

...しかし、これは特に醜く、多形ではないようです。一般的にそのような状況に対処するためのクリーンな方法は何ですか?

編集:確かに、doSomething()の実装をクラスAとBにプッシュできれば簡単ですが、それが意味をなさない状況ではどうでしょうか?つまり、doSomething()はクラスCで定義されており、実装はCの内部状態に大きく依存しています。

4

7 に答える 7

6

それは簡単です:

public interface X {
  int doSomething();
}

public class A implements X {
  public int doSomething() {
    // implementation in A
  }  
}

public class B implements X {
  public int doSomething() {
    // implementation in B
  }  

}

更新: OK、C の状態と A/B の違いに依存するアルゴリズムが C にあるようです。次に、そのアルゴリズムを分割して、C クラスが A と B の両方に共通の実装のみを持ち、A/B 依存部分が C で呼び出される同じメソッドの特定の実装として適切なクラスに移動するようにします。可能であれば、C の状態を A と B の doSomething に部分的に渡すことができます

于 2012-10-03T10:54:04.053 に答える
4

doSomethingAの実装をクラスAdoSomethingBにプッシュし、インターフェースclassBで定義して呼び出すだけです( double-dispatchの行の何か)。doSomethingXx.doSomething()

orX型であることに対する処理の依存性に関する質問の最新の編集を考慮すると、演算子は、基礎となる実装クラスへの強い依存関係を確立し、装飾されたものに渡されるとコードが惨めに失敗するため、使用しないでください。実例。ABinstanceofX xC.doSomething()

私の知る限り、 の実装は、 または のいずれかC.doSomething()からの情報を使用する必要があるポイントにまで煮詰められ、その時点で実行されるステップは、およびのメソッドに抽象化され、 interface で宣言される必要があります。これにより、 の新しい実装も、 に依存するこのメソッドを実装するようになり、コードの保守性が向上します。HTH。ABABXXC

于 2012-10-03T10:53:54.320 に答える
2

これを行う正しい方法は、訪問者パターン

于 2012-10-03T10:54:19.633 に答える
0

それは設計上の問題です。doSomething()のAおよびB実装がCオブジェクトの状態に大きく依存している場合は、引数として渡すことができます:x.doSomething(C c)


インターフェイスXでdoSomething()を作成します。

public interface X {
   doSomething(C c);
}

public class A extends X {
   doSomething(C c) {
    ...
   }
}

public class B extends X {
   doSomething(C c) {
    ...
   }
}

次に、最初のメソッドは次のようになります。

public void doSomething(X x) {
  x.doSomething(C c);
}
于 2012-10-03T11:00:25.403 に答える
0

まず第一に、私は拡張するのではなくインターフェースを実装します:)そして私の最初の考えはこのようになるでしょう

  class Parent {
      public Parent() {

      }
    }

    class Child extends Parent {
      public Child() {
        super();
      }
    }

    public class MainClass {
      public static void main(String[] a) {

        Child child = new Child();
        if (child instanceof Parent) {
          System.out.println("true");
        }

      }

    }
于 2012-10-03T10:55:15.900 に答える
0
 public interface X {
     doSomeThing();
    }

public class A implement X {
  doSomeThing(){}
}

public class B implement X {
   doSomeThing() {}
}

今、あなたは使用することができます

  X a = new A();
  a.doSomeThing();
于 2012-10-03T10:55:40.077 に答える
0

do something() をインターフェイス X に移動できますか? 次に、インスタンスのキャストまたは使用を必要とせずに x.do something() を呼び出すだけです。

于 2012-10-03T10:55:45.260 に答える