[英]Passing an ArrayList of subclass to a constructor that takes ArrayList of superclass?
Okay so I'm working on this project for the university and I think I'm doing something wrong here, guess I haven't understood java subclassing and class inheritance enough. 好的,所以我正在为这所大学开展这个项目,我想我在这里做错了,我猜我还没有理解java继承和类继承。
I have rewrote my problem in this little form. 我用这个小形式改写了我的问题。
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
}
}
In little words I wrote a lot of classes that extend one more general class, and in many places I have made operations with the superclass (the general one), instead of treating each of the subclasses one by one in the same way. 简而言之,我编写了许多扩展一个通用类的类,并且在许多地方我使用超类(一般类)进行操作,而不是以相同的方式逐个处理每个子类。
But I can not create the instance of the class I need, since the constructor takes as argument the superclass. 但是我无法创建我需要的类的实例,因为构造函数将超类作为参数。 I don't even know how to cast it since
new VeryBigClass(new (ArrayList<SuperClass>)ArrayList<SubClass>());
因为
new VeryBigClass(new (ArrayList<SuperClass>)ArrayList<SubClass>());
我甚至不知道如何转换它new VeryBigClass(new (ArrayList<SuperClass>)ArrayList<SubClass>());
is obviously wrong. 显然是错的。 Plus, the construction of these instances will be handled by a json library at some point so I'd rather not do such fancy stuff...
另外,这些实例的构建将在某个时候由json库处理,所以我宁愿不做这些花哨的东西......
If you use generics, it should work just fine, is not the same a list of Superclass than a list of Subclass, but the generic solve this: 如果你使用泛型,它应该工作得很好,不是一个超类列表而不是一个子类列表,但通用解决了这个:
class VeryBigClass<T extends SuperClass> {
ArrayList<T> superList;
public VeryBigClass(ArrayList<T> superList) {
this.superList = superList;
}
}
The Java Tutorial explains this in http://docs.oracle.com/javase/tutorial/java/generics/inheritance.html Java Tutorial在http://docs.oracle.com/javase/tutorial/java/generics/inheritance.html中解释了这一点。
Bottom line, if you have types with an inheritance relationship, like Sub extends Super
as generics, they do not confer an inheritance relationship in the classes that hold them: Foo<Sub>
is not a subtype of Foo<Super>
. 换句话说,如果您有具有继承关系的类型,例如
Sub extends Super
为泛型,则它们不会在包含它们的类中赋予继承关系: Foo<Sub>
不是Foo<Super>
的子类型。
The reason is that it would violate the promise of what type the generic type contains, breaking the Liskov Substitution principle. 原因是它违反了泛型类型所包含的类型的承诺,违反了Liskov Substitution原则。 If
List<Sub>
extended List<Super>
, it would be legal to do this: 如果
List<Sub>
扩展List<Super>
,则执行此操作是合法的:
List<Sub> subs = new ArrayList<Sub>();
List<Super> supers = subs;
Super super = new Super();
supers.add(super);
Whoa! 哇! Now
subs
has an element of type Super
, completely illegal! 现在
subs
有一个Super
类型的元素,完全违法!
Because ArrayList<Sub>
is not a subtype of List<Super>
, when you invoked 因为
ArrayList<Sub>
不是List<Super>
的子类型,所以在您调用时
new VeryBigClass(new ArrayList<SubClass>());
you passed an argument to the constructor that was not legal. 您将参数传递给不合法的构造函数。
You can also use the wildcard ? extends super
你也可以使用通配符
? extends super
? extends super
That is, any class that extends super. ? extends super
即任何扩展超级的类。
Example : 示例 :
class VeryBigClass {
ArrayList<? extends SuperClass> superList;
public VeryBigClass(ArrayList<? extends SuperClass> superList) {
this.superList = superList;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.