0

同じ入力パラメーターの型と同じ戻り値の型 (ただし名前は異なる) を持つ2 つのクラスABそのようなメソッドがあり、それぞれメソッドをB extends A実装しているとします。タイプorのオブジェクトを入力として取得するメソッドで、オブジェクトがタイプである場合、またはオブジェクトがタイプである場合に呼び出したいと思います。getAgetBpublic static <T extends A> void print(T t)ABgetAAgetBB

Aとのコードを編集できれば、 (との実装では、それぞれ getA() と getB() を呼び出す) を提供Bするインターフェイスを実装し、からこのメソッドを呼び出します。問題は、クラス A と B が変更できないことです! . メソッドを追加または変更することはできず、それらのクラス階層は固定されており、私はそれらのコードを記述しておらず、ソースにアクセスすることもできません。IgetValue()ABgetValue()print()

Aこれは、何らかの理由でとのコードを変更したくない場合にも適用されることに注意してくださいB

を使用せずにそうする方法はありinstanceofますか?

instanceofここでは、 (悪い!)を使用するソリューションに従います。

public class Test {

    public static <T extends A> void print(T t){
        if (t instanceof B)
            System.out.println(((B)t).getB());
        else if (t instanceof A)
            System.out.println(t.getA());
    }

    public static class A {
        public String getA(){
            return "A";
        }
    }
    public static class B extends A {
        public String getB(){
            return "B";
        }
    }

}

4

3 に答える 3

5

何らかの理由で元のコードにアクセスできない場合は、instanceof などに頼らざるを得なくなります。これらの場合、それ自体は悪くありません - あなたの手は縛られています.

私がすることは、あなたのTでジェネリック化されたラッパークラスを作成し、あなたが提案したgetValueようにテストするaを与え、このクラスが存在する唯一の理由は、Aまたはを使用するための一貫したインターフェースを提供することであることを明確にすることですa B. それはまだグロスですが、グロスさを 1 か所に収めました。instanceof

于 2012-12-18T18:14:04.497 に答える
3

Matt の答えを拡張するために、これらのクラスにFacade パターンを採用することを検討します。これは、これら 2 つのクラスから必要なすべての機能をラップするために、別のクラス (または 2 つ) を作成することを意味します。Matt が示唆するように、これにはメソッドの追加が含まれます。

利点は、制御できない API からアプリケーションを分離できることです。元のライブラリのすべてのメソッドを必要としない場合は、API を簡素化する機会もあります。

于 2012-12-18T18:22:18.240 に答える
0

ありがとう、そして@マット。これは間違いなく最もクリーンな方法だと思います。instanceof を使用しない完全なコードを提供します。

public static void main(String[] args){
    A a = new A();
    B b = new B();
    AWrapper aw = new AWrapper(a);
    BWrapper bw = new BWrapper(b);
    print(aw);
    print(bw);
}

public static void print(Wrapper t){
    System.out.println(t.getValue());
}

public static class A {
    public String getA(){
        return "A";
    }
}
public static class B extends A {
    public String getB(){
        return "B";
    }
}

public static interface Wrapper{
    public String getValue();
}

public static class AWrapper implements Wrapper{
    A a;
    public AWrapper (A a){
        this.a = a;
    }
    public String getValue(){
        return a.getA();
    }
}

public static class BWrapper implements Wrapper{
    B b;
    public BWrapper (B b){
        this.b = b;
    }
    public String getValue(){
        return b.getB();
    }
}
于 2012-12-19T16:09:19.983 に答える