Java ArrayList实例化

Java ArrayList instantiation

本问题已经有最佳答案,请猛点这里访问。

我只想知道为什么我们初始化父类的对象并用子类实例化它,而不是直接实例化子类对象。

Sample:

1
List<String> sampleList=new ArrayList<String>();

而不是

1
ArrayList<String> sampleList=new ArrayList<String>();


假设我创建了一个方法来处理ArrayList

1
2
3
4
5
6
7
public int sum(ArrayList<Integer> list){
   int sum = 0;
   for(Integer x : list){
      sum += x;
   }
   return sum;
}

到目前为止,这还可以,任何拥有ArrayList的人都可以称之为EDOCX1。但是那些有LinkedList的人呢?他们运气不好!

但我为什么要排除它们呢?我的函数实际上并没有使用任何特定于ArrayList的东西-我实际上不关心或不需要知道给定函数的List类型。那么,为什么不尽可能地使其通用化,这样任何拥有List的人都可以调用我的函数呢?

1
2
3
4
5
6
7
public int sum(List<Integer> list){
   int sum = 0;
   for(Integer x : list){
      sum += x;
   }
   return sum;
}

同样地,如果我不关心某个变量是什么类型的List,为什么要将它声明为ArrayList?如果我以后想把这个变量改成一个LinkedList?如果我声明它是一个List,那么这是一行更改。但是如果我声明它是一个ArrayList,那么我必须更改对它的每个引用。在大型项目中,这会变得非常烦人,所以通常最好尽可能保持变量的通用性。


你的问题至少在以下方面是错误的:

  • List sampleList部分中,我们不"初始化父类的对象",这只是类型声明。

  • 在实例化对象之前,不能对其进行初始化。

  • 实际上,我们实例化类,而不是对象。类实例化的结果是一个对象。

  • List不是"父类",它是一个接口。接口根本无法实例化/初始化。

  • 如果我们从您的问题中消除所有这些错误,并改为"为什么我们要声明一个通用类型的变量",那么答案是它使代码更可读和更可维护:这样,您就保证不会使用ArrayList的任何细节,而是严格地将其用作通用List。当在方法参数中使用时,这变得更加重要:它允许您的方法与任何List实现一起使用,从而使您的方法更加有用。这就是多态性的本质所在。


    首先,列表是接口而不是类。其次,多态性是面向对象编程中的一个重要概念。

    使用对父类(或由该类实现的接口)的引用的用例是,如果您希望使用该引用迭代该父类的不同子类。

    你可能对这条线感兴趣。