好的,所以我正在为这所大学的这个项目工作,我想我在这里做错了什么,我猜我还没有理解java子类化和类继承。
我已经用这个小形式改写了我的问题。
class SuperClass {
int dunno;
public SuperClass(int dunno) {
this.dunno = dunno;
}
}
class SubClass extends SuperClass {
int duncare;
public SubClass(int dunno, int duncare) {
super(dunno);
this.duncare = duncare;
}
}
class VeryBigClass {
ArrayList<SuperClass> superList;
public VeryBigClass(ArrayList<SuperClass> superList) {
this.superList = superList;
}
}
public void main(String[] args) {
new VeryBigClass(new ArrayList<SubClass>()); // this is the problematic line
}
}
简单地说,我编写了许多扩展一个通用类的类,并且在许多地方我使用超类(一般类)进行操作,而不是以相同的方式逐个处理每个子类。 。
但是我无法创建我需要的类的实例,因为构造函数将超类作为参数。我甚至不知道如何施展它,因为new VeryBigClass(new (ArrayList<SuperClass>)ArrayList<SubClass>());
显然是错误的。另外,这些实例的构建将由json库在某个时刻处理,所以我宁愿不做这些花哨的东西...
答案 0 :(得分:6)
如果你使用泛型,它应该工作得很好,与超类的列表不同,而不是子类列表,但通用解决了这个:
class VeryBigClass<T extends SuperClass> {
ArrayList<T> superList;
public VeryBigClass(ArrayList<T> superList) {
this.superList = superList;
}
}
答案 1 :(得分:4)
Java Tutorial在http://docs.oracle.com/javase/tutorial/java/generics/inheritance.html
中解释了这一点从底线开始,如果您有具有继承关系的类型,例如Sub extends Super
作为泛型,那么不会在包含它们的类中赋予继承关系:Foo<Sub>
不是Foo<Super>
的子类型。
原因是它违反了泛型类型所包含的类型的承诺,违反了Liskov Substitution原则。如果List<Sub>
延长List<Super>
,则执行此操作是合法的:
List<Sub> subs = new ArrayList<Sub>();
List<Super> supers = subs;
Super super = new Super();
supers.add(super);
哇!现在subs
有Super
类型的元素,完全非法!
因为ArrayList<Sub>
不是List<Super>
的子类型,所以当您调用
new VeryBigClass(new ArrayList<SubClass>());
您将参数传递给不合法的构造函数。
答案 2 :(得分:2)
您还可以使用通配符? extends super
即任何扩展超级的类。
示例强>:
class VeryBigClass {
ArrayList<? extends SuperClass> superList;
public VeryBigClass(ArrayList<? extends SuperClass> superList) {
this.superList = superList;
}
}