java - 设计 Java 通用层次结构以避免模板类冲突

标签 java generics inheritance collections

考虑以下原始类型形式的 Java 泛型类层次结构。

class A ...
class B extends A ...
class C extends A ...

使用 A 类中的方法并在 B 和 C 中重写。

String foo() ...
String bar(A a) ...

我们可以成功进行以下调用。

String r = (new B()).foo();
String r = (new B()).bar(new C());

这里的真正目标是将 A 的实例保存在容器中 并处理它们,而不考虑我们有哪一种 A。

A fred;
List as = new LinkedList();
for (A a : as) ... fred.bar(a); ...

可以毫无问题地构造 B 类和 C 类的对象并将其传递给 foo。 现在我们介绍泛型。

class A<T,U,V> ...
class B<T> extends A<T,Void,Object> ...
class C<N> extends A<String,Void,Object> ...

使用 A 类中的方法并在 B 和 C 中重写。

T foo() ...

然后我们做出以下合理的调用。

String r = (new A<String,Void,Object>()).foo();
String r = (new B<String>()).foo();
String r = (new C<Integer>()).foo();

String r = (new B<String>()).foo();
String r = (new B<String>()).bar(new C<Integer>());

这里的真正目标是将 A 的实例保存在容器中 并处理它们,而不考虑我们有哪一种 A。

A<String,String,Integer> fred;
List<A<String,String,Integer>> as = new LinkedList<>();
for (A a : as) ... fred.bar(a); ...

这些决定使得无法将类型 B 和 C 的对象加载到“as”列表中, 由于通用模板中的类型冲突。

请注意,这是一个现有的软件,我正在尝试清除警告。

最佳答案

如果你只关心foo()的返回值,那么你可以使用这个:

List<A<String, ?, ?>> as = ...;

这将允许您存储 AA 的任何子类型,其中 T 的类型参数为 String >,但可以使用 UV 的任何内容。所以:

as.add(new A<String, String, Integer>()); // fine
as.add(new B<String>()); // fine
as.add(new C<Integer>()); // fine

as.add(new A<Double, String, Integer>()); // won't compile

但是,您将无法调用参数类型为 UVA 方法。如果这是一个问题,那么似乎您必须以某种方式重新设计。

可能还可以看到:

关于java - 设计 Java 通用层次结构以避免模板类冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51446680/

相关文章:

java - 从java访问xml字符串

java - 在运行时,查找 Java 应用程序中扩展基类的所有类

c# - 基于 Type 变量创建通用对象

java - 泛型、方法签名、赋值

java - 为什么我可以在不以任何方式指定其类型且无法推断类型的情况下创建通用对象?

c# - 不一致的可访问性 : Base Class is less accessible than class

java - 在一个父类(super class)集合中的不同对象(扩展公共(public)父类(super class))上循环

java - 我发送 7 条消息抛出 GCM 并收到 35 条消息的响应

java - 如何使用基本身份验证创建具有适当权限的用户来列出 kubernetes v1.13 中的命名空间

java - 当没有任何内容被重写时,为什么我会收到构造函数中可重写方法调用的警告?