【问题标题】:Superclass type or subclass type [duplicate]超类类型或子类类型[重复]
【发布时间】:2013-07-08 10:37:47
【问题描述】:

有什么区别

LinkedList<String> l1 = new LinkedList<String>();
List<String> l2 = new LinkedList<String>();

为什么l2 类型没有方法addFirstl1 类型有方法addFirst?即使他们都是 持有LinkedList 对象? 与我从 Gosling 的“Java 编程语言”中读到的相反 这表明该对象将是您所创造的, 在这种情况下,我将其设为LinkedListnew LinkedList(),即使 它是列表类型

那我应该如何正确申报呢?

Collection<String> c = new LinkedList<String>();
List<String> c = new LinkedList<String>();
LinkedList<String> c = new LinkedList<String>();

【问题讨论】:

    标签: java list collections linked-list


    【解决方案1】:

    为什么 l2 类型没有方法 addFirst 而 l1 类型有方法 addFirst?

    因为l2的编译时类型只是List&lt;E&gt;,而List&lt;E&gt;没有声明addFirst方法。

    作为一个更简单的例子,考虑:

    Object x = "hello";
    int invalid = x.length(); // This is invalid
    

    在执行时,x 会引用一个String 对象,但变量本身的类型只是Object,所以不能调用String.length() 方法。

    在这里区分三个不同的术语非常重要:

    • 一个变量,它的类型基于它的声明方式
    • 引用(例如引用类型变量的值)
    • 一个对象(有一个类型)

    变量的值(假设它不是原始变量)是一个引用。该引用可以是null,也可以引用与变量类型赋值兼容的类型的对象。

    所以在上面的例子中:

    • x 的类型是Object
    • x 的值是一个参考
    • 该引用在执行时引用了 String 类型的对象

    【讨论】:

    • 感谢您的回答!所以你的意思是......我应该始终确保编译期间的类型应该与执行期间引用指向的对象相补充。
    【解决方案2】:
    LinkedList<String> l1 = new LinkedList<String>();
    

    这里l1是LinkedList的实例

    List<String> l2 = new LinkedList<String>();
    

    这里l2是List的实例

    l2 没有方法 addFirst 因为 List 接口不包含该方法,而 LinkedList 包含该方法。但是在您的代码中的任何时候,您都可以将 l2 转换为 linkedList 并可以调用 addFirst() 方法。

    【讨论】:

      【解决方案3】:

      List l2 = new LinkedList();

      当您有一个只接受SuperClass 实例的方法时,这很有用。由于SubClass 是一个 SuperClass,因此您可以使用SubClass 的实例并将其视为SuperClass

      这就是多态性。它允许您在不破坏其余代码的情况下更改类内部的实现。

      【讨论】:

        猜你喜欢
        • 2017-04-06
        • 1970-01-01
        • 2013-10-17
        • 1970-01-01
        • 2021-01-01
        • 1970-01-01
        • 2016-05-28
        • 2011-12-05
        • 1970-01-01
        相关资源
        最近更新 更多