[英]How to define a generic List in an abstract super class?
I'm trying to create an abstract class with an abstract method, which should be able to return any type of a list with items extending a SuperBean
. 我正在尝试使用抽象方法创建一个抽象类,它应该能够返回包含扩展SuperBean
项的任何类型的列表。
Later I then want to create a generic class which can add items to that lists. 后来我想创建一个可以在该列表中添加项目的泛型类。 Example: 例:
class AbstractService<T extends SuperBean> {
//this is what I'm aiming for
void add(T item) {
// "is not applicable for the arguments (T)"
superBean.getSublist().add(item);
}
}
abstract class SuperBean {
abstract List<? extends SuperBean> getSublist();
}
class MyBean1 extends SuperBean {
List<MyBean2> sublist;
List<MyBean2> getSublist() {
return sublist;
}
}
class MyBean2 extends SuperBean {
List<MyBean3> sublist;
List<MyBean3> getSublist() {
return sublist;
}
}
Question: how to I have to define the abstract getSublist()
class so that I can add any T item
that is an implementation of SuperBean
? 问:如何将我必须定义abstract getSublist()
类,这样我可以添加任何T item
即是一个实现SuperBean
?
You will need to add to your generics in AbstractService
: 您需要在AbstractService
添加到泛型:
// Add S to be T's type parameter Add <S> to SuperBean here
class AbstractService<S extends SuperBean, T extends SuperBean<S>> {
// I'm assuming superBean is defined here.
T superBean;
//this is what I'm aiming for
void add(S item) {
superBean.getSublist().add(item);
}
}
Next, you will need to make SuperBean
generic, with its subclasses defining the generic type parameter <T>
: 接下来,您将需要使SuperBean
泛型,其子类定义泛型类型参数<T>
:
abstract class SuperBean<T extends SuperBean> {
// Now you can define the abstract method properly:
abstract List<T> getSublist();
}
Each subclass defines its generic type parameter appropriately: 每个子类都适当地定义其泛型类型参数:
class MyBean1 extends SuperBean<MyBean2> {
List<MyBean2> sublist;
List<MyBean2> getSublist() {
return sublist;
}
}
And MyBean2
is defined similarly: 并且MyBean2
的定义类似:
class MyBean2 extends SuperBean<MyBean3> {
List<MyBean3> sublist;
List<MyBean3> getSublist() {
return sublist;
}
}
This allows you to declare services as follows: 这允许您按如下方式声明服务:
AbstractService<MyBean2, MyBean1> service1 = new AbstractService<MyBean2, MyBean1>();
AbstractService<MyBean3, MyBean2> service2 = new AbstractService<MyBean3, MyBean2>();
Your generic parameters don't make sense here. 您的通用参数在这里没有意义。 If you make the generic types explicit, you can see where it's going wrong: 如果你明确地使用泛型类型,你可以看到它出错的地方:
Add the generic parameter to your SuperBean
: 将泛型参数添加到SuperBean
:
abstract class SuperBean<T extends SuperBean> {
abstract List<T> getSublist();
}
and make that type explicit in the subtypes: 并在子类型中明确指出该类型:
class MyBean1 extends SuperBean<MyBean2> {
List<MyBean2> sublist;
List<MyBean2> getSublist() {
return sublist;
}
}
Now, in your service, you would have 现在,在您的服务中,您将拥有
class AbstractService<T extends SuperBean<S>> {
void add(T item) {
// you cannot do this because the items in the sublist of
// your super bean are of the wrong type.
superBean.getSublist().add(item);
}
}
The alternative would be to make the service as 另一种方法是将服务作为
class AbstractService<T extends SuperBean<T>>
Then you would be able to add items to the sublist, but your beans are not of the right type. 然后,您可以将项目添加到子列表,但您的bean不是正确的类型。 For instance, MyBean1
does not extend SuperBean<MyBean1>
, but it extends SuperBean<MyBean2>
. 例如, MyBean1
不扩展SuperBean<MyBean1>
,但它扩展了SuperBean<MyBean2>
。
I'm not sure if this is what you want, but doesn't produce errors. 我不确定这是否是你想要的,但不会产生错误。
There are two abstract declarations, SuperBean and AbstractService (though AbstractService is defined, I assume that it should be abstract). 有两个抽象声明,SuperBean和AbstractService(虽然定义了AbstractService,但我认为它应该是抽象的)。
There are three declarations that are not abstract, MyBean{1,2,3} 有三个非抽象的声明,MyBean {1,2,3}
I define awSuperBean just to see if it works. 我定义awSuperBean只是为了看它是否有效。
The code you pasted doesn't have a (-grr- concrete) superBean defined yet. 您粘贴的代码尚未定义(-grr-具体)superBean。 So, I define a superBean called awSuperBean and use it in the (abstract?) add method. 所以,我定义了一个名为awSuperBean的superBean,并在(abstract?)add方法中使用它。
. 。 . 。
/// testing superbean implementation
//
class awSuperBean<MyBean1> extends SuperBean {
List<MyBean1> getSublist() { return new java.util.ArrayList<MyBean1>(); }
}
//
///
class AbstractService<T extends SuperBean> {
/// tests a superbean definition
//
awSuperBean<T> asuperBean;
//this is what I'm aiming for
void add(T item) {
// "is not applicable for the arguments (T)"
/// use the superbean
asuperBean.getSublist().add(item);
}
}
/// every defined SuperBean subtype will need to specify the type
// of SuperBean it will produce in it's getSublist call
//
abstract class SuperBean<getSublist extends SuperBean> {
/// use the type parameter
//
abstract List<getSublist> getSublist();
}
I think you should only use the parametric type identifier, T, in the abstract classes. 我认为你应该只在抽象类中使用参数类型标识符T. Use the declared types in the superbean subtype definitions instead of confusing Ts. 在superbean子类型定义中使用声明的类型而不是混淆Ts。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.