【问题标题】:Java generic parameters and inheritanceJava 泛型参数和继承
【发布时间】:2011-08-03 13:43:01
【问题描述】:

假设我们知道 ViewGroup 扩展了 View。
此外,我们还有一个通用的参数化class A<T extends View>

问题:
为什么方法C.add() 不接受new A<ViewGroup>() 作为参数?
由于多态性,它不应该工作吗?

解决方案:? extends View 唱歌添加让添加接受new A<ViewGroup>() 作为参数。

【问题讨论】:

标签: java generics inheritance polymorphism


【解决方案1】:

您将add 方法签名为:

static void add(A<View>)

但你的意思可能是:

static void add(A<? extends View> a)

【讨论】:

  • 这仍然行不通,因为new A&lt;ViewGroup&gt;() 无效。
  • @tskuzzy 你是什么意思?就像new ArrayList&lt;ViewGroup&gt;()
  • OP 在问题中有错字。他原本说View扩展了ViewGroup。 :P
  • Thnx,用 add(A&lt;? extends View&gt; a) 签名 add 让 add() 接受 new A&lt;ViewGroup&gt;() thnx。对不起,我最初的错字。
【解决方案2】:

不完全是因为add() 可能正在使用View 中没有的ViewGroup 方法。

总结:ViewViewGroup,但 ViewGroup 不是 View。多态性是您可以将 View 对象分配给 ViewGroup 声明的地方。

【讨论】:

  • 您说“我们知道 View 扩展了 ViewGroup”。 o_o
  • 对不起......当然 ViewGroup 扩展了 View,就像在类图上一样
【解决方案3】:

首先,您的问题不是很清楚,因为 UML 图与您的文字相矛盾。您说 View 扩展了 ViewGroup,但图表显示相反:ViewGroup 扩展了 View。

现在,List&lt;Car&gt; 不会扩展 List&lt;Vehicle&gt;。如果是这样的话,你可以这样做:

List<Car> listOfCars = new ArrayList<Car>();
List<Vehicle> listOfVehicles = listOfCars;
listOfVehicles.add(new Bicycle());
// now the list of cars contain a bicycle. Not pretty. 

【讨论】:

  • 对不起,刚刚编辑了句子,当然ViewGroup extends View在这里。
【解决方案4】:

首先你说 View 扩展了 ViewGroup,但图中说 ViewGroup 扩展了 View(我认为这是正确的)。

其次,您不能将List&lt;ViewGroup&gt; 作为List&lt;View&gt; 传递。这是一种编译时保护,可防止有人将 AnotherView 添加到此列表中并损害泛型的类型安全。

List&lt;ViewGroup&gt; 不是List&lt;View&gt; 的子类型,但它是List&lt;? extends View&gt; 的子类型。因此,您可以修改您的方法以改为接受 List&lt;? extends View&gt;,但请注意,您不能以这种方式添加到传递给该方法的列表中。

还有另一种语法称为下限通配符 (List&lt;? super ViewGroup&gt;),与上面提到的上限通配符相反,它使您可以添加到列表中,但您可以传入 ViewGroup 或其父项的列表。

更多关于泛型中的通配符可以在这里找到:http://download.oracle.com/javase/tutorial/java/generics/wildcards.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多