4

インターフェイス MyInterface と、MyInterface を実装する 2 つのクラス A、B があるとします。、および の
2 つのオブジェクトを宣言しました。 関数に渡そうとすると、関数にエラーが発生します。MyInterface a = new A()MyInterface b = new B()
doSomething(A a){}

これは私のコードです:

public interface MyInterface {}

public class A implements MyInterface{}

public class B implements MyInterface{}

public class Tester {

    public static void main(String[] args){
        MyInterface a = new A();
        MyInterface b = new B();
        test(b);
    }

    public static void test(A a){
        System.out.println("A");
    }

    public static void test(B b){
        System.out.println("B");
    }

}

私の問題は、あらゆる種類のクラスになる可能性のあるコンポーネントインターフェイスから取得していて、各クラスの関数を作成する必要があることです。
したがって、1 つの方法は、インターフェイスを取得し、それがどのタイプであるかを確認することです。(A のインスタンス)

他の人がこの問題にどのように対処しているか知りたいです??

どうも

4

10 に答える 10

5

各クラスが実装するインターフェースにメソッドを持たせることはできませんか? または、インターフェイスを制御できませんか?

これにより、ポリモーフィズムが提供され、外部メソッドを定義する必要がなくなります。これはインターフェイスの意図だと思います。これにより、クライアントは、それを実装するすべてのクラスを非型固有の方法で処理できるようになります。

インターフェイスに追加できない場合は、適切なメソッドを使用して 2 つ目のインターフェイスを導入することをお勧めします。インターフェイスもクラスも編集できない場合は、インターフェイスをパラメーターとして持つメソッドが必要であり、具体的なクラスを確認します。ただし、これは最後の手段であり、インターフェイスの使用を覆し、メソッドをすべての実装に結び付けます。

于 2008-09-30T22:39:18.307 に答える
3

あなたはこのような何かを求めているようです:

public static void test(MyInterface obj){
  if(obj instanceof A) {
     A tmp = (A)obj;
  } else if(obj instanceof B) {
     B tmp = (B)obj;
  } else {
     //handle error condition
  }
}

ただし、これは非常に悪い形式であり、デザインに重大な問題があることを示していることに注意してください。インターフェイスを制御できない場合は、marcjが提案しているように、2番目のインターフェイスを追加するのが良い方法かもしれません。バイナリ互換性を維持しながらこれを行うことができることに注意してください。

于 2008-09-30T22:44:52.520 に答える
2

あなたが実際に何を求めているのかはわかりませんが、問題は MyInterface 型のパラメーターを取るメソッドがないことです。Java の正確な構文はわかりませんが、 if (b is B) { test(b as B) } のようなことはできますが、私はしません。ジェネリックにする必要がある場合は MyInterface 型を変数型として使用し、それ以外の場合は変数型として B を使用します。インターフェイスを使用する目的を無効にしています。

于 2008-09-30T22:38:35.330 に答える
1

この問題を完全に理解しているかどうかはわかりませんが、test()メソッドを子クラスに移動する方法が1つあるようです。

public interface MyInterface {    
    public void test();
}

public class A implements MyInterface{
    public void test() {
        System.out.println("A");
    }
}

public class B implements MyInterface{
    public void test() {
        System.out.println("B");
    }
}

public class Tester {

    public static void main(String[] args){
        MyInterface a = new A();
        MyInterface b = new B();
        b.test();
    }
}

同様に、toString()メソッドを使用して、その結果を出力することもできます。しかし、あなたの要件がこれを不可能にするかどうかは、質問からは完全にはわかりません。

于 2008-09-30T22:42:15.880 に答える
1

ここでは、ビジターデザイン パターンが役立つと思います。基本的な考え方は、どのメソッドを呼び出すかを決めるのではなく、クラス (A と B) が適切なメソッド自体を呼び出すようにすることです。C# の人間として、Java が機能することを願っています。

public interface Visitable {   
   void accept(Tester tester) 
}

public interface MyInterface implements Visitable {    
}

public class A implements MyInterface{
   public void accept(Tester tester){
       tester.test(this);
   }
}

public class B implements MyInterface{
   public void accept(Tester tester){
       tester.test(this);
   }
}

public class Tester {

    public static void main(String[] args){
        MyInterface a = new A();
        MyInterface b = new B();
        a.accept(this);
        b.accept(this);
    }

    public void test(A a){
        System.out.println("A");
    }

    public void test(B b){
        System.out.println("B");
    }

}
于 2008-09-30T22:40:23.873 に答える
1

1 つの .java ファイルで 1 つのパブリック クラス/インターフェイスのみを使用してください。そうしないと、エラーがスローされます。そして、オブジェクト名でオブジェクトを呼び出します.Teaterクラスのみで2つのメソッドを宣言しました.次に、クラスA、Bを宣言する目的は何ですか。

于 2012-06-20T09:08:24.023 に答える
0
public interface MyInterface {}

public class A implements MyInterface{}

public class B implements MyInterface{}

public class Tester {

    public static void main(String[] args){
       MyInterface a = new A();
       MyInterface b = new B();
       test(b); // this is wrong
    }

    public static void test(A a){
        System.out.println("A");
    }

    public static void test(B b){
        System.out.println("B");
    }

}

MyInterfaceのようなサブタイプを持つ引数で定義されたメソッドに、参照変数によって参照されるオブジェクトを渡そうとしていますtest(B b)MyInterface参照変数は のサブタイプである任意のオブジェクトを参照できますが、MyInterface必ずしも のオブジェクトであるとは限りませんB。これが Java で許可されている場合、実行時エラーが発生する可能性があるため、コンパイラはここでエラーを出します。概念をより明確にする例を挙げてください。クラスのコードを変更しB、メソッドを追加しました。

public class B implements MyInterface {
    public void onlyBCanInvokeThis() {}

}

test(B b)以下のようにメソッドを変更するだけです:

public static void test(B b){
    b.onlyBCanInvokeThis();
    System.out.println("B");
}

コンパイラで許可されている場合、このコードは実行時に爆発します。

 MyInterface a = new A();
 // since a is of type A. invoking onlyBCanInvokeThis()
 // inside test() method on a will throw exception.
 test(a); 

これを防ぐために、コンパイラは、スーパークラス参照を使用したこのようなメソッド呼び出し手法を許可しません。


何を達成しようとしているのかはわかりませんが、実行時のポリモーフィズムを達成したいようです。MyInterfaceこれを実現するには、メソッドを宣言し、それを各サブクラスに実装する必要があります。このようにして、メソッドの呼び出しは、参照型ではなくオブジェクト型に基づいて実行時に解決されます。

public interface MyInterface {    
    public void test();
}

public class A implements MyInterface{
    public void test() {
        System.out.println("A");
    }
}

public class B implements MyInterface{
    public void test() {
        System.out.println("B");
    }
}

public class Tester {

    public static void main(String[] args){
        MyInterface a = new A();
        MyInterface b = new B();
        b.test(); // calls B's implementation of test()
    }
}
于 2013-05-14T13:42:39.460 に答える
0

私は通常、次のように抽象クラスを使用してこの問題を回避します。

public abstract class Parent {}
public class A extends Parent {...}
public class B extends Parent {...}

これにより、A または B を取る関数に Parent オブジェクトを渡すことができます。

于 2008-09-30T22:40:09.663 に答える
0

次の 3 つのオプションがあります。

  1. 訪問者パターン; MyInterface タイプを変更してvisit(Visitor)Visitorクラスに各サブクラスにアクセスするためのメソッドが多数含まれるメソッドを含める必要があります。
  2. if-elseメソッド内で使用してtest(MyInterface)、それらの間をチェックします
  3. チェーンを使用します。つまり、 handler などを宣言しますATester。これらはすべて、 method を持つBTesterインターフェイスを実装します。次に、処理を行う前に型が A と等しいことを確認します。次に、メインの Tester クラスにこれらのテスターのチェーンを作成し、各インスタンスを処理できる に到達するまでチェーンに渡します。これは基本的に、ブロックを 2 から別のクラスに変えています。ITestertest(MyInterface)ATesterMyInterfaceITesterif-else

個人的には、ほとんどの状況で 2 を選択します。Java には真のオブジェクト指向がありません。それに対処してください!それを回避するさまざまな方法を考え出すと、通常、コードを理解するのが難しくなります。

于 2008-09-30T22:48:41.637 に答える
0

a) MyInterface にメソッドを配置して A と B に実装することでポリモーフィズムを活用するか、b) Composite と Visitor のデザイン パターンを組み合わせて使用​​する必要があるようです。a) から始めて、扱いにくくなったら b) に向かいます。

訪問者に関する私の広範な考え:

http://tech.puredanger.com/2007/07/16/visitor/

于 2008-10-01T04:46:16.303 に答える