【问题标题】:Can we use AbstractList instead of the List interface to hold an Arraylist instance?我们可以使用 AbstractList 而不是 List 接口来保存 Arraylist 实例吗?
【发布时间】:2014-10-14 11:10:17
【问题描述】:

一般我们用代码来接口:

List<String> list  = new ArrayList<String>();

我们能写出以下内容吗?

AbstractList<String> list  = new ArrayList<String>();

这种特殊初始化的缺点是什么?任何见解将不胜感激。

【问题讨论】:

标签: java collections


【解决方案1】:

将列表定义为AbstractList 会将您的实现绑定到AbstractList 的子类,而使用List 接口允许您分配给list 变量该接口的任意实现。

将列表定义为AbstractList 还可以让您访问(无需强制转换)AbstractList 的方法,这些方法不属于List 接口,但使用它们会使您的代码不太灵活。

如果你没有很好的理由这样做,就不要这样做。

【讨论】:

    【解决方案2】:

    主要缺点是一般性的:在 Java 中,一次只能从一个类继承,而您可以实现任意数量的接口。

    如果 list 是私有或局部变量,则初始化为接口几乎没有任何优势。你会更好

    ArrayList<String> list  = new ArrayList<String>();
    

    但是,如果您有一个公共字段或方法参数,则最好使用最不具体的声明:接口。抽象类也实现了接口,所以可以使用。但是您的类的使用者可以使用任何实现该接口的类,而该类可以从他们可能喜欢的任何其他类继承。

    【讨论】:

      【解决方案3】:

      使用List&lt;String&gt; 优于AbstractList&lt;String&gt; 的优势在于List 指定了一个契约,而AbstractList 指定了一个(部分)实现。使用List 可确保您的代码与List 的任何实现兼容,而不仅仅是从AbstractList 派生的那些。

      虽然在变量声明方面遵循这种做法似乎没什么大不了的,但在整个代码中遵循这种用法可确保整个应用程序具有更大的灵活性。

      【讨论】:

        【解决方案4】:

        像这样使用AbstractList 的一个缺点是您限制自己使用扩展AbstractList 的列表类。在没有AbstractList 作为超类的情况下实现List 接口是完全可能的。

        第二个缺点是无法编译:

        List<String> list = new ArrayList<String>();
        
        AbstractList<String> list2 = list;
        

        Java 类型系统不会让您假设每个List&lt;String&gt; 都是AbstractList&lt;String&gt;

        【讨论】:

          猜你喜欢
          • 2018-04-04
          • 1970-01-01
          • 1970-01-01
          • 2015-06-22
          • 1970-01-01
          • 2021-08-16
          • 1970-01-01
          • 1970-01-01
          • 2022-01-15
          相关资源
          最近更新 更多