5

让我们看下面的例子:

public class BothPaintAndPrintable implements Paintable,Printable{
    public void print() {}
    public void paint() {}
}
public interface Paintable {
    public void paint();
}

public interface Printable {
    public void print();
}

public class ITest {
    ArrayList<Printable> printables = new ArrayList<Printable>();
    ArrayList<Paintable> paintables = new ArrayList<Paintable>();
    public void add(Paintable p) {
        paintables.add(p);
    }
    public void add(Printable p) {
        printables.add(p);
    }
    public static void main(String[] args) {
        BothPaintAndPrintable a= new BothPaintAndPrintable();
        ITest t=new ITest();
        t.add(a);//compiliation error here
    }
}

如果我希望BothPaintAndPrintable将实例添加到每个 ArrayLists 怎么办?一种方法是使用BothPaintAndPrintable参数重载方法,但我正在尝试寻找替代方案,因为这样做可能会降低代码的可重用性。有人有其他想法吗?

4

4 回答 4

7

您需要第三个重载:

public <T extends Object&Paintable&Printable> void add(T t) {
  paintables.add(t);
  printables.add(t);
}

这使得擦除add(Object),因此它不会与其他方法冲突,但它确实限制了对Paintable和的实现者的输入Printable

(Guava不得不Joinerwith Iteratorand使用这个技巧Iterable,因为一些邪恶的类同时实现了这两者,尽管这是一个糟糕的主意。)

于 2012-08-01T15:36:12.517 回答
2

我会采用一般add(Object o)方法,然后检查instanceof,并将其Object放入相应的列表中。

如果传递的Object两个接口都没有实现,那么抛出一个InvalidArgumentException可能是个好主意。

于 2012-08-01T15:30:00.907 回答
0

不确定最佳答案,因为我找不到我真正喜欢的方式!

您可以使用泛型,但我既不喜欢“instanceof”测试,也不喜欢所需的演员表:

import java.util.ArrayList;

class BothPaintAndPrintable implements Paintable, Printable {
    public void print() {
    }

    public void paint() {
    }
}

interface Paintable {
    public void paint();
}

interface Printable {
    public void print();
}

 public class ITest<T> {
    ArrayList<Printable> printables = new ArrayList<Printable>();

    ArrayList<Paintable> paintables = new ArrayList<Paintable>();

    public void add(T p) {
        if (p instanceof Paintable) {
            paintables.add((Paintable) p);
        }
        if (p instanceof Printable) {
            printables.add((Printable) p);
        }
    } 

    public static void main(String[] args) {
        BothPaintAndPrintable a = new BothPaintAndPrintable();
        ITest<BothPaintAndPrintable> t = new ITest<BothPaintAndPrintable>();
        t.add(a);
    }
}
于 2012-08-01T15:38:06.863 回答
0

好的,我确实喜欢正确的答案;但是,我应该向 OP 指出另一种解决方案。

public static void main(String[] args) {
    BothPaintAndPrintable a= new BothPaintAndPrintable();
    ITest t=new ITest();
    t.add((Paintable)a);
    t.add((Printable)a);
}

这可以在不添加第三个成员的情况下工作,即使您决定在以后添加更多接口也可以工作。

于 2012-08-01T17:16:37.857 回答