让我们看看下面的例子:
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
参数重载方法,但我正在尝试查看替代方法,因为这样做可能会降低代码的可重用性。有没有人有另一个想法?
答案 0 :(得分:7)
你需要第三次重载:
public <T extends Object&Paintable&Printable> void add(T t) {
paintables.add(t);
printables.add(t);
}
这会删除add(Object)
,因此它不会与其他方法发生冲突,但它确实会限制Paintable
和Printable
的实现者的输入。
(Joiner
与Iterator
和Iterable
的番石榴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);
}
这可以在不添加第三个成员的情况下工作,如果你决定在路上添加更多接口,它甚至可以工作。