泛型的继承有什么问题
What is wrong with inheritance of generic
我有一个关于泛型的问题。
我定义了基础 类 ServiceObject
和 ServiceObjectsList
class ServiceObject {};
class ServiceObjectsList<T extends ServiceObject> extends ArrayList<T> {};
然后我定义了一些后代类:
class UserServiceObject extends ServiceObject {};
class UserServiceObjectsList extends ServiceObjectsList<UserServiceObject> {};
class ItemServiceObject extends ServiceObject {};
class ItemServiceObjectsList extends ServiceObjectsList<ItemServiceObject> {};
// etc...
现在我需要将 UserServiceObjectsList
视为 ServiceObjectsList<ServiceObject>
:
如果我写:
ServiceObjectsList displayableServiceObjects;
那我就不能遍历它们了:
for (ServiceObject serviceObject : displayableServiceObjects)
抛出错误"Incompatible types".
如果我写ServiceObjectsList<ServiceObject> displayableServiceObjects
那么我无法分配 UserServiceObjects
:
displayableServiceObjects = new UserServiceObjects();
它抛出完全相同的 "Incompatible types" 错误;
我做错了什么?
所有 ServiceObject
s,ServiceObjectsList
s 和他们的后代确实需要。然后封装一些功能。
您不能将您的列表视为 ServiceObjectsList<ServiceObject>
,因为那不是它的本来面目。不允许转换。
然而,您可以将列表转换为 ServiceObjectsList<? extends ServiceObject>
- 扩展 ServiceObject
.
的列表
您应该在声明中指定泛型类型:
ServiceObjectsList<? extends ServiceObject> displayableServiceObjects;
"Incompatible types" 错误将消失...
简短的回答是我认为你想要实现的是做不到的,因为 ArrayList 和 ArrayList 并不是真正分开的 类它们在 C++ 中,其中模板更像是聪明的宏,而不是 Java 泛型。
当您定义 class ServiceObjectsList<T extends ServiceObject> extends ArrayList<T> {}
时,您已经创建了 ArrayList 的适当子类,但 ServiceObjectsList 仍然是通用的。那么当你声明一个变量ServiceObjectsList displayableServiceObjects;
而不加类型参数时,它和ServiceObjectsList<Object>
是一样的。限定符 <T extends ServiceObject>
将在编译时检查,但前提是您在变量上声明了类型参数。
我有一个关于泛型的问题。
我定义了基础 类 ServiceObject
和 ServiceObjectsList
class ServiceObject {};
class ServiceObjectsList<T extends ServiceObject> extends ArrayList<T> {};
然后我定义了一些后代类:
class UserServiceObject extends ServiceObject {};
class UserServiceObjectsList extends ServiceObjectsList<UserServiceObject> {};
class ItemServiceObject extends ServiceObject {};
class ItemServiceObjectsList extends ServiceObjectsList<ItemServiceObject> {};
// etc...
现在我需要将 UserServiceObjectsList
视为 ServiceObjectsList<ServiceObject>
:
如果我写:
ServiceObjectsList displayableServiceObjects;
那我就不能遍历它们了:
for (ServiceObject serviceObject : displayableServiceObjects)
抛出错误"Incompatible types".
如果我写ServiceObjectsList<ServiceObject> displayableServiceObjects
那么我无法分配 UserServiceObjects
:
displayableServiceObjects = new UserServiceObjects();
它抛出完全相同的 "Incompatible types" 错误;
我做错了什么?
所有 ServiceObject
s,ServiceObjectsList
s 和他们的后代确实需要。然后封装一些功能。
您不能将您的列表视为 ServiceObjectsList<ServiceObject>
,因为那不是它的本来面目。不允许转换。
然而,您可以将列表转换为 ServiceObjectsList<? extends ServiceObject>
- 扩展 ServiceObject
.
您应该在声明中指定泛型类型:
ServiceObjectsList<? extends ServiceObject> displayableServiceObjects;
"Incompatible types" 错误将消失...
简短的回答是我认为你想要实现的是做不到的,因为 ArrayList 和 ArrayList 并不是真正分开的 类它们在 C++ 中,其中模板更像是聪明的宏,而不是 Java 泛型。
当您定义 class ServiceObjectsList<T extends ServiceObject> extends ArrayList<T> {}
时,您已经创建了 ArrayList 的适当子类,但 ServiceObjectsList 仍然是通用的。那么当你声明一个变量ServiceObjectsList displayableServiceObjects;
而不加类型参数时,它和ServiceObjectsList<Object>
是一样的。限定符 <T extends ServiceObject>
将在编译时检查,但前提是您在变量上声明了类型参数。