我需要一个List
来保存扩展类X的对象,并实现接口Y.
我试过this,但我意识到这不是我真正需要的。
考虑一下:
class Test<T extends MyBaseClass & MyBaseInterface>
{
public List<T> myList;
}
public abstract class MyBaseClass {}
public interface MyBaseInterface {}
public class MyDerivedClassA extends MyBaseClass implements MyBaseInterface {}
public class MyDerivedClassB extends MyBaseClass implements MyBaseInterface {}
Test<MyDerivedClassA> obj = new Test<MyDerivedClassA>();
obj.myList.add(new MyDerivedClassA()); // Works
obj.myList.add(new MyDerivedClassB()); // Compile error
这会在编译时使obj.myList
成为List<MyDerivedClassA>
。我需要的是让myList
包含可以任何类的对象列表,前提是它扩展MyBaseClass
和实现{{1 }}。这意味着在示例中,MyBaseInterface
应该有效。
这个例子更接近我的需要。
myList.add(new MyDerivedClassB())
我需要的是在编译时实现类型安全。这个问题是关于Java和泛型的,所以请不要给我答案,比如设计模式(即使用策略设计模式)。
答案 0 :(得分:2)
如果您可以控制对列表的访问,您可以使列表只包含MyBaseClass
的实例,但只能通过带有额外约束的特殊方法添加到列表中:
private List<MyBaseClass> list;
<T extends MyBaseClass & MyBaseInterface> boolean add(T e) {
return list.add(e);
}
现在,作为该类的作者,您知道列表中的所有实例都可以安全地转换为MyBaseInterface
,并将它们直接用作MyBaseClass
。
这非常简洁,但如果你必须,那么你可以选择的元素,只要你负责确保它们的安全 - 编译器只能这么做。
答案 1 :(得分:0)
介绍一个“中级”抽象类:
class Test<T extends MyBaseClass & MyBaseInterface>
{
public List<T> myList;
}
abstract class MyBaseClass {}
interface MyBaseInterface {}
class MyDerivedClassA extends DerivedClass {}
class MyDerivedClassB extends DerivedClass {}
class DerivedClass extends MyBaseClass implements MyBaseInterface {}
然后您可以使用
Test<DerivedClass> obj = new Test<>();
obj.myList.add(new MyDerivedClassA()); // Works
obj.myList.add(new MyDerivedClassB()); // Works