接口 - 解决模糊错误

时间:2012-08-01 15:22:10

标签: java interface

让我们看看下面的例子:

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 个答案:

答案 0 :(得分:7)

你需要第三次重载:

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

这会删除add(Object),因此它不会与其他方法发生冲突,但它确实会限制PaintablePrintable的实现者的输入。

JoinerIteratorIterable的番石榴had to use this trick,因为其中有一些邪恶的类实现了两者,即使这是一个糟糕的主意。)< / p>

答案 1 :(得分:2)

我会使用常规add(Object o)方法,然后检查instanceof,并将Object放入相应的列表中。

如果传递的Object没有实现任何接口,则抛出InvalidArgumentException可能是个好主意。

答案 2 :(得分: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);
    }
}

答案 3 :(得分:0)

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

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

这可以在不添加第三个成员的情况下工作,如果你决定在路上添加更多接口,它甚至可以工作。