0

假设我有两个类AB这样B extends A,分别实现方法getA并且getB具有相同的输入参数类型和相同的返回类型(但名称不同)。在将 or 类型的对象作为输入的方法中,如果对象是类型或public static <T extends A> void print(T t)对象是A类型,B我想调用。getAAgetBB

如果我可以编辑 and 的代码,AB会让它们实现一个接口I提供(在andgetValue()的实现中,将分别调用 getA() 和 getB()),然后从. 问题是:A 类和 B 类不可修改!. 不能添加或更改任何方法,它们的类层次结构是固定的,我没有编写它们的代码,也无权访问源代码。ABgetValue()print()

请注意,这也适用于 - 出于任何原因 - 我不想更改Aand的代码的情况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测试instanceof,并明确说明这个类存在的唯一原因是提供一个一致的接口来使用 A 或A B. 它仍然很恶心,但你已经把恶心控制在了一个地方。

于 2012-12-18T18:14:04.497 回答
3

为了扩展马特的回答,我会考虑为这些类采用外观模式。这意味着您创建一个单独的类(或两个)来包装这两个类所需的所有功能。正如马特建议的那样,这包括添加一个方法。

好处是您将应用程序与您无法控制的 API 分离。如果您不需要原始库中的所有方法,您还有机会简化 API。

于 2012-12-18T18:22:18.240 回答
0

谢谢你和@Matt。猜猜这绝对是最干净的方法。将提供不使用 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 回答