2

私は Java に比較的慣れていないので、次の質問について何か助けていただければ幸いです。A2 つのクラスを定義しました - 簡単にするために、それらを と と呼びましょうBClass Aには という名前のメソッドがありmethodA、という名前Class BのメソッドがありmethodBます。これら 2 つのクラスのオブジェクトは、ArrayList呼び出された に含まれていcontainerます。私がする必要があるのは、をループして、ArrayListオブジェクトのタイプに応じて異なるメソッドを呼び出すことです。

これは現在私のコードです:

for (Object item : container) {
    if (item instanceof A) {
        item.methodA()
    } else if (item instanceof B) {
        item.methodB() 
    }
}

itemタイプにorがないため、私の IDE (NetBeans) は上記のコードをコンパイルObjectしません。必要なことを達成するためにループを記述する他の方法はありますか? ありがとう。methodAmethodB

4

4 に答える 4

5

キャストを追加する必要があります。アイテムが A (または B) のインスタンスであることを確認したからといって、アイテムで A メソッドを呼び出すことはできません。

if (item instanceof A) {
    ((A) item).methodA();
} else if (item instanceof B) {
    ((B) item).methodB();
}

ただし、一般的には、このパターンを回避するためにコードを再構築することを検討することをお勧めします。たとえば、A と B の両方が実装する基本クラスの共通インターフェイスを作成できます。

public interface MyInterface { 
    void doSomething();
}

class A : MyInterface {
    ...
    public void doSomething() { this.methodA(); }
}


class B : MyInterface {
    ...
    public void doSomething() { this.methodB(); }
}

次に、次のことができます。

List<MyInterface> list = // a list of A's and B's
for (MyInterface item : list) { 
    // use polymorphism to invoke the appropriate method
    item.doSomething(); 
}

ビジター パターンは、このタイプのコードのもう 1 つの一般的なソリューションです。これは、クラスを常に変更することなく、クラスの固定セット全体でさまざまな一般的な操作をサポートしたい場合に役立ちます。

于 2013-06-30T18:52:12.897 に答える
2

Java(および他のほとんどの広く使用されている言語)には適切な答えがないバリアントの問題に取り組んでいます。Scala はケース クラスでそれを解決し、ML のようなアカデミックな言語はそれを簡単に処理します。

上記のすべての回答は、if-ladders とキャストを使用することを示唆しています。これは、Java で最も簡潔なソリューションですが、基本的にコンパイル時の完全な安全性を放棄します。キャストが気に入らない場合は、ビジター パターンを使用して問題を回避できます。これは可能な限り冗長ですが、完全にタイプ セーフです。

interface ABVariantVisitor {
    void visit( A a );
    void visit( B b );
}

interface ABVariant {
    void accept( ABVariantVisitor v );
}

class A implements ABVariant {
    // ...
    void accept( ABVariantVisitor v ) {
        v.visit( this );
    }
    // ...
}

class B implements ABVariant {
    // ...
    void accept( ABVariantVisitor v ) {
        v.visit( this );
    }
    // ...
}

List< ABVariant > container;

// ...

for ( ABVariant item : container ) {
    item.accept( new ABVariantVisitor() {
        @Override void visit( A a ) {
            a.methodA();
        }
        @Override void visit( B b ) {
            b.methodB();
        }
    } );
}
于 2013-06-30T20:56:13.087 に答える
0

メソッドを呼び出す前に、A または B に型キャストを行うだけです。メソッドを呼び出す前に項目を A または B に変換します。

for (Object item : container) {
    if (item instanceof A) {
       ((A) item).methodA();;
    } else if (item instanceof B) {
       ((B) item).methodB();
    }
}
于 2013-06-30T18:52:52.623 に答える
0

Try in this way

       if (item instanceof A) {
            ((A) item).methodA();
        } else if (item instanceof B) {
            ((B) item).methodB();
        }
于 2013-06-30T18:59:17.293 に答える