Java:扩展/实现两个类/接口的对象列表

时间:2017-03-20 06:56:48

标签: java generics

我需要一个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和泛型的,所以请不要给我答案,比如设计模式(即使用策略设计模式)。

2 个答案:

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