A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘佳 中级黑马   /  2012-8-30 11:06  /  2379 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 刘佳 于 2012-8-31 07:46 编辑

List a = new ArrayList();
ArrayList a = new ArrayList();
Collection a = new ArrayList();
上述三种建集合对象的方式有何区别?

评分

参与人数 1黑马币 +15 收起 理由
张立江 + 15

查看全部评分

10 个回复

倒序浏览
Collection是List的父类,List是ArrayList的父类,这就是多态了。
List a = new ArrayList();
父类引用指向子类对象,a只能使用List中有的方法,而ArrayList()的特有方法不能使用。
ArrayList a = new ArrayList();
这个就不是多态了,中规中矩的建立对象,可以使用a自身所有的方法。
Collection a = new ArrayList();
和第一个一样父类的引用指向子类的对象,a只能使用Collection中的方法,ArrayList特有的方法或者从List处覆写的特有方法(如List特有迭代器ListIterator)不能使用。
具体有哪些特有方法可以查阅API文档。
回复 使用道具 举报
黑马张旭明 发表于 2012-8-30 11:30
Collection是List的父类,List是ArrayList的父类,这就是多态了。
List a = new ArrayList();
父类引用指向 ...

一般用哪种方式比较好?
回复 使用道具 举报
首先说一下ArrayList  List  Collection 三者的关系:
ArrayList是List的实现类,List又是Collection的子类型
List a = new ArrayList();//父类应用指向子类对象
ArrayList a = new ArrayList();//只是ArrayList类的实例化
Collection a = new ArrayList();//父类的父类应用指向子类对象
其实上述语句中:
List a = new ArrayList();
Collection a = new ArrayList();
就是所谓的“多态”。

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1 新人鼓励

查看全部评分

回复 使用道具 举报
首先要明确Collection与List都是接口,List是Collection的子接口,而ArrayList是List的实现类,也就是Collection的实现类。List a = new ArrayList();表示生成a引用指向ArrayList()对象,子类指向父类引用,所以可以使用LIst接口里列出的方法,而不能使用ArrayList私有的方法。Collection a = new ArrayList()也是一样的道理。ArrayList a = new ArrayList()中的就是本类实例化,和一般的类的用法一样的。不知道这么说你明白 吗?

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1 新人鼓励

查看全部评分

回复 使用道具 举报
刘佳 发表于 2012-8-30 11:37
一般用哪种方式比较好?

看情况而定吧,要用这个类中独有的方法当然是ArrayList a= new ArrayList()这种方式好。当定义一个方法method (参数),里面的参数如果是ArrayList a 的话那就只能传ArrayList类型的,如果定义的是List a的话就能传LinkedList和ArrayList类型的,可以说增加了扩展性。还有匿名子类对象等都用到了多态。
回复 使用道具 举报
陈莹 中级黑马 2012-8-30 12:18:20
7#
这是多态,你可以类比来考虑这个问题,Collection就是爷爷,List就是爸爸,ArrayList就是儿子。在你的这三个例子中,不存在List和Collection的转换,所以,你把Collection和List都当做ArrayList的父类来考虑就行。
List a = new ArrayList();
ArrayList a = new ArrayList();
Collection a = new ArrayList();
这是向上转型,也就是说子类转换成父类对象(父类不能转换成子类),利用动态绑定技术,可以在运行的时候根据父类引用变量所指对象的实际类型执行相应的子类方法,从而实现多态性。
多态,是面向对象的程序设计语言最核心的特征。多态,意味着一个对象有着多重特征,可以在特定的情况下,表现不同的状态,从而对应着不同的属性和方法。从程序设计的角度而言,例如:
public interface Parent(){
  public void show();
}
public class Child_1 implements Parent{
public void show(){
   ……
}
}
public class Child_2 implements Parent{
  public void showl(){
    ……
  }
}

Parent pa = new Child_1();
pa.show()则显然是调用Child_1的方法;
Parent pa = new Child_2();
pa.show()则是在调用Child_2的方法。所以,我们对于抽象的父类或者接口给出了我们的具体实现后,pa 可以完全不用管实现的细节,只访问我们定义的方法,就可以了。事实上,这就是多态所起的作用。也就是说,将子类类型的指针赋值给父类类型的指针,之后,父亲的行为像儿子,而不是儿子的行为像父亲。
回复 使用道具 举报
陈莹 发表于 2012-8-30 12:18
这是多态,你可以类比来考虑这个问题,Collection就是爷爷,List就是爸爸,ArrayList就是儿子。在你的这三 ...

1、请问一下 你说的 动态绑定技术 子类重写父类方法 是同一个原理吗
回复 使用道具 举报
陈莹 中级黑马 2012-8-30 20:41:38
9#
赵伟闯 发表于 2012-8-30 17:10
1、请问一下 你说的 动态绑定技术 子类重写父类方法 是同一个原理吗

不是,子类重写父类方法是子类中的方法跟父类的一样,所以就覆盖了父类的方法,那样的话,子类在调用该方法时调用的是自己的方法,假如你没有覆写父类的这个方法,你也可以调用该方法,因为你从父类继承了该方法,相当于你自己也有该方法,只是你的方法跟父类的这个方法一模一样。
看下面这个例子:
  1. class Parent
  2. {
  3.                 public void show()
  4.           {
  5.                         System.out.println("调用Parent的show方法!");
  6.       }
  7.           public void showParent()
  8.          {
  9.             System.out.println("调用父类的方法!");
  10.           }
  11. }
  12. class Child_1 extends Parent
  13. {
  14.            public void show()
  15.                 {
  16.                                 System.out.println("调用Child_1的show方法!");
  17.                 }
  18. }
  19. class Child_2 extends Parent
  20. {
  21.      public void show()
  22.           {
  23.                         System.out.println("调用Child_2的show方法!");
  24.            }
  25. }
  26. public class Demo
  27. {
  28.         public static void main(String args[])
  29.     {
  30.                 Parent pa1 = new Child_1();
  31.                 pa1.show();
  32.                 pa1.showParent();
  33.                 Parent pa2 = new Child_2();
  34.                 pa2.show();
  35.     }
  36. }
复制代码
Parent pa1 = new Child_1();在执行期间,因为父类指向了子类Child_1对象,所以,父类具有了子类的行为,就会执行子类的方法,所以pa1.show()这句话执行的结果是:
调用Child_1的show方法!
当执行pa1.showParent();因为子类没有覆写该方法,所以结果仍然为:调用父类的方法!
动态绑定是指在执行期间决定哪个方法被调用或哪个属性被访问。不知你明白了没有?
记得毕老师讲过一个例子:
毕老师的父亲会讲课,毕老师继承了这个特征,然后毕老师自己还有自己的特有特征,会看电影,那么假如毕老师假扮成毕老师的父亲,就是Parent pa1 = new Child_1();那么,这个父亲(毕老师假扮的)就既能讲课,又会看电影。但是假如毕老师的父亲假扮成毕老师,他就不具备看电影这个特征。
动态绑定就是毕老师假扮的父亲在执行期间,执行相应子类,也就是毕老师的方法。
回复 使用道具 举报
本帖最后由 任文杰 于 2012-8-30 21:10 编辑

首先,我说下前两个:
List a = new ArrayList();
ArrayList a = new ArrayList();

第一个a是List接口的实例,可以再被赋值为所有实现了List接口的类或其子类的实例,这个list变量a可以当作List接口及其其父接口作为参数传递。而下面那个a变量表示ArrayList类的实例,必须是ArrayList类或其子类的实例才可以赋值给这个a变量,这个a变量可以当作ArrayList类或其父类作为参数传递,也可以作为ArrayList类及其父类实现了的接口类型作为参数传递(例如List接口)。
总的说来是多态的应用了。
如果你到最后这个a变量只用作ArrayList类的实例,那么你大可以用下面那种方式,但是上面那种方式更灵活,比如你现在把它赋值为new ArrayList()。那么完全可以把它当作ArrayList类的实例来用,然后用完了你还可以把它赋值为其他的实现了List接口的类的实例或当作其他的实例来用。

至于Collection也就是第三种:
Collection a = new ArrayList();

和List a = new ArrayList();用法差不多,Collection也是接口,并且是接口List的父接口,两者在用法上没太大的区别。
回复 使用道具 举报
陈莹 发表于 2012-8-30 20:41
不是,子类重写父类方法是子类中的方法跟父类的一样,所以就覆盖了父类的方法,那样的话,子类在调用该方 ...

恩 谢谢了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马