Java中通配符泛型的继承

时间:2017-03-24 07:02:36

标签: java generics

因为我们可以做到

ArrayList<?> l = new ArrayList<Integer>();

我们可以说ArrayList<?>ArrayList<Integer>的超类吗? 上面的例子是否描述了多态性?

更新:一般来说,如果A<T>B<T>的超类,那么

A<?> obj = new B<Integer>();

那么说A<?>B<Integer>的超类是正确的吗?

2 个答案:

答案 0 :(得分:2)

TLDR

  

我们可以说ArrayList<?>ArrayList<Integer>的超类吗?

但我们可以说它是ArrayList<Integer>

的超类型
  

然后说A<?>B<Integer>的超类?

是正确的

,我们也可以说它是B<Integer>

的超类型

另请注意,继承仅在子类或超类的上下文中使用,而不是在子类型或超类型中使用。

Quick Reference

首先要了解的是java中的class is a type。 我们将在下面看到,无论有效使用术语sub / super class,使用sub / super类型都是有效的,反之亦然

现在让我定义超类。根据{{​​3}}

  

给出C<F1,...,Fn>的一个(可能是通用的)类声明(n≥0,   C≠Object)(这里的Fi是类型参数),类类型C<F1,...,Fn>的直接超类是   如果是C的声明的extends子句中给出的类型   存在extends子句,否则为Object。

     

C<F1,...,Fn>(n> 0)成为泛型类声明。直接   参数化类类型C<T1,...,Tn>的超类,其中Ti(1≤   i≤n)是一个类型(参数),是D<U1 θ,...,Uk θ>,其中D<U1,...,Uk>是   直接超类C<F1,...,Fn>,θ是替换   [F1:= T1,...,FN:= Tn的]。

     

如果满足以下任一条件,则A类是C类的子类:

     

a)A是C的直接子类b)存在B类,即A   是B的子类,B是C的子类,应用此定义   递归。

     

当A是子类时,C类被认为是A类的超类   C。

用简单的单词解释这个问题,请考虑一个更简单的例子: 上述定义中C<F1,...,Fn>ArrayList<T>C<T1,...,Tn>将为ArrayList<Integer>T是类型参数,我们使用Integer实例化它,它是类型参数。

JLS 8.1.4

现在,A<?>是否包含A<Integer>的extends子句? (我知道问这样的结构是愚蠢的,但让我们严格定义)。不,不是的。通常,在扩展中,我们一共提到了不同的类类型。

现在,让我们看看sub / super类型的定义。截至[ What did we meant by θ is the substitution [F1:=T1,...,Fn:=Tn] ? ]

  

给定泛型类型声明C<F1,...,Fn>(n> 0),直接   参数化类型C<T1,...,Tn>的超类型,其中Ti(1≤i≤   n)是一种类型,是以下所有:

     
      
  1. D<U1 θ,...,Uk θ>,其中D<U1,...,Uk>是一个泛型类型   泛型C<T1,...,Tn>的直接超类型和θ是   替换[F1:= T1,...,Fn:= Tn]。

  2.   
  3. C<S1,...,Sn>,其中Si含有Ti(1≤i≤n)(§4.5.1)。

  4.   
  5. 类型为Object,如果C<F1,...,Fn>是通用接口类型,则为no   直接超接口。

  6.   
  7. 原始类型C

  8.   

现在通过这个定义,根据第2点

  

C<S1,...,Sn>,其中Si含有Ti(1≤i≤n)(§4.5.1)。

?包含IntegerJLS 4.10.2)。因此,这使得A<?>的{​​{1}}超类型。

您可以轻松地看到此定义的第1点,包括子类定义本身。

问题的第二部分,我们已经说A<Integer>扩展A<T>,使其属于两种定义。

最后,我们看到继承意味着什么。截至Reference

  

C类直接超类继承所有具体   方法m(包括静态和实例)的全部超类   以下是真实的:[...]

答案 1 :(得分:0)

此处继承适用于泛型类而非泛型参数

也就是说ArrayList<?>不是ArrayList<Integer>

的超类

它是具有不同类型参数的同一类。如果您使用除<?>以外的任何其他类型参数,则代码将无效。即使是Integer的超类