Java:扩展/实现两个类/接口的对象列表
我需要一个Java:扩展/实现两个类/接口的对象列表,java,generics,Java,Generics,我需要一个列表,它保存扩展类X的对象,并实现接口Y 我试过了,但我意识到这不是我真正需要的 public abstract class Animal {} public abstract class Mammal extends Animal {} public abstract class Bird extends Animal {} public class Tiger extends Mammal {} public class Ostrich extends Bird {} publ
列表
,它保存扩展类X的对象,并实现接口Y
我试过了,但我意识到这不是我真正需要的
public abstract class Animal {}
public abstract class Mammal extends Animal {}
public abstract class Bird extends Animal {}
public class Tiger extends Mammal {}
public class Ostrich extends Bird {}
public interface RunningObject {}
public class RunningTiger extends Tiger implements RunningObject {}
public class RunningOstrich extends Ostrich implements RunningObject {}
public class RunningRobot extends NonAnimal implements RunningObject {}
// This line is syntactically wrong
public List<Animal & RunningObject> runningAnimals = new List<>();
runningAnimals.add(new RunningTiger()); // This should work
runningAnimals.add(new RunningOstrich()); // This should work
runningAnimals.add(new Tiger()); // This should give compile error
runningAnimals.add(new Ostrich()); // This should give compile error
runningAnimals.add(new RunningRobot()); // This should give compile error
考虑这一点:
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
我需要的是在编译时实现类型安全性。这个问题是关于Java和泛型的,所以请不要给我关于设计模式(即使用策略设计模式)之类的问题的答案。如果您可以控制对列表的访问,您可以使列表只包含
MyBaseClass
的实例,但只能通过带有额外约束的特殊方法添加到列表中:
private List<MyBaseClass> list;
<T extends MyBaseClass & MyBaseInterface> boolean add(T e) {
return list.add(e);
}
私有列表;
布尔加法(TE){
返回列表。添加(e);
}
现在,作为该类的作者,您知道列表中的所有实例都可以安全地强制转换到MyBaseInterface
,也可以直接作为MyBaseClass
使用
这是相当令人讨厌的,但如果必须,可以对元素进行强制转换,前提是您负责确保它们的安全性-编译器只能做这么多。引入一个“中级”抽象类:
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 {}
类测试
{
公开名单;
}
抽象类MyBaseClass{}
接口MyBaseInterface{}
类MyDerivedClassA扩展了DerivedClass{}
类MyDerivedClassB扩展了DerivedClass{}
类DerivedClass扩展MyBaseClass实现MyBaseInterface{}
然后你可以和我一起去
Test<DerivedClass> obj = new Test<>();
obj.myList.add(new MyDerivedClassA()); // Works
obj.myList.add(new MyDerivedClassB()); // Works
testobj=新测试();
obj.myList.add(新的MyDerivedClassA());//作品
obj.myList.add(新的MyDerivedClassB());//作品
MyDerivedClassB类不是MyDerivedClassA类。尝试“Test obj=new Test();”&
运算符不适用于?
通配符,否则我就不会用Test
类包装列表。@Jai ok,我删除了前两个选项。这意味着我不能直接将列表暴露在类之外,我必须手动编写列表中所有我想在这个类之外公开的方法?谢谢。这在技术上是正确的方法,但在实践中我很难实现这一点。我当然想直接公开一个列表,它可以通过list.add()
等方法接收正确的编译时对象。这与我的要求相近,但我的实际问题实际上比这更复杂。见更新的问题。