黑马程序员技术交流社区

标题: ArrayList和多态的一点问题 [打印本页]

作者: 轻语。    时间: 2014-4-15 22:06
标题: ArrayList和多态的一点问题
本帖最后由 伍叶竹 于 2014-4-15 22:50 编辑
  1. import java.util.*;
  2. class Person
  3. {
  4.         private String name;
  5.         private int age;
  6.         Person(String name,int age)
  7.         {
  8.                 this.name = name;
  9.                 this.age = age;
  10.         }
  11.         
  12.         public String getName()
  13.         {
  14.                 return name;
  15.         }
  16.         public int getAge()
  17.         {
  18.                 return age;
  19.         }
  20. }

  21. class ArrayListTest2
  22. {
  23.         public static void sop(Object obj)
  24.         {
  25.                 System.out.println(obj);
  26.         }
  27.         public static void main(String[] args)
  28.         {
  29.                 ArrayList al = new ArrayList();
  30.         
  31.                 al.add(new Person("lisi01",30));//al.add(Object obj)//Object obj = new Person("lisi01",30);被提升了?            
  32.                 al.add(new Person("lisi02",32));
  33.                 al.add(new Person("lisi03",33));
  34.                 al.add(new Person("lisi04",35));

  35.                 Iterator it = al.iterator();

  36.                 while(it.hasNext())
  37.                 {
  38.                         sop(it.next().getName()+"::"+it.next().getAge());//出错。Object无getName()和getAge()方法。附图。换成下述两行不出错。
  39.                         //Person p = (Person)it.next();
  40.                         //sop(p.getName()+"::"+p.getAge());
  41.                 }
  42.         }
  43. }

  44. /*
复制代码
                 =====================================================================
我所知道的是:add方法的参数类型是Object。以便于接收任意类型对象。所以32行处,实质是al.add(Object obj);
                Object obj = new Person("lisi01",30);  所以是被提升了。add中不是Person类了,自然识别不来get方法。
这些是我知道的。可是不太懂。 求高手细致讲解。

===========================================================================
                另外。API文档中,ArrayList中add方法。有两个: boolean add(element e);
                                                                        void add(int index,element e);
               
上例中add是其中之一的应用吗?如何理解?




作者: 曹冬明    时间: 2014-4-15 22:17
  1. import java.util.*;
  2. class Person
  3. {
  4.         private String name;
  5.         private int age;
  6.         Person(String name,int age)
  7.         {
  8.                 this.name = name;
  9.                 this.age = age;
  10.         }
  11.         
  12.         public String getName()
  13.         {
  14.                 return name;
  15.         }
  16.         public int getAge()
  17.         {
  18.                 return age;
  19.         }
  20. }

  21. class ArrayListTest2
  22. {
  23.         public static void sop(Object obj)
  24.         {
  25.                 System.out.println(obj);
  26.         }
  27.         public static void main(String[] args)
  28.         {
  29.                 ArrayList al = new ArrayList();
  30.         
  31.                 al.add(new Person("lisi01",30));//al.add(Object obj)//Object obj = new Person("lisi01",30);被提升了?            
  32.                 al.add(new Person("lisi02",32));
  33.                 al.add(new Person("lisi03",33));
  34.                 al.add(new Person("lisi04",35));

  35.                 Iterator it = al.iterator();//这里要加泛型改成Iterator<Person> it = al.iterator()

  36.                 while(it.hasNext())
  37.                 {
  38.                         sop(it.next().getName()+"::"+it.next().getAge());//出错。Object无getName()和getAge()方法。附图。换成下述两行不出错。
  39.                         //Person p = (Person)it.next();
  40.                         //sop(p.getName()+"::"+p.getAge());
  41.                 }
  42.         }
  43. }

  44. /*
复制代码
37行我帮你加注释教你怎么改了!不过估计你可能还没有学到泛型。iterator里存的是Object类型对象的引用,你it.next().getName(),当然不行了,因为Object类中没有这个方法。不用泛型的话,你要坐下强转:Person p = (Person)it.next().然后用p.getName(),就不会有问题了!!!- -希望能帮到你

作者: 香菜病病患    时间: 2014-4-15 22:28
本帖最后由 香菜病病患 于 2014-4-15 22:41 编辑

boolean add(element e);
void add(int index,element e);
这两个是重载的应用而不是多态的应用。
上面那个方法是在集合末尾加元素,下面那个方法是在指定的索引处插入元素,然后那个索引位置原来的元素和后面的元素都会向后顺延一个位置。



”我所知道的是:add方法的参数类型是Object。以便于接收任意类型对象。所以32行处,实质是al.add(Object obj);
                Object obj = new Person("lisi01",30);  所以是被提升了。add中不是Person类了,自然识别不来get方法。
这些是我知道的。可是不太懂。 求高手细致讲解“

以上双引号内的内容是引用你说的话。关于多态,你已经知道为什么识别不来get方法了,那么关于这点我就不说了。
我就说说多态有些什么实际的应用。举个例子:面向接口编程
(估计你应该还没学到泛型,我就省略泛型了)
ArrayList list=new ArrayList();
List list =new ArrayList();   (用父类引接收子类实例就是典型面向接口编程)
对比一下上面两句话。我们在编程时可能一开始是用的ArrayList 但是你写到一半突然发现用LinkedList的性能会更好。
此时就要改源代码了,假设你是用上面那种定义方式定义的集合。
如果你的代码中没有用到ArrayList中特有的方法,那么改起来还比较方便,但用到的话可能一改就一大片了。
但是如果你用的是下面那句的话,由于list中定义的是ArrayList共性和LinkedList集合中的共性内容,所以此时只要改一处就可以了。
所以写代码时,能用父类引用来接收的就尽量用父类引用。而我们自己写类时也是,要将共性内容定义到父类中。

作者: 满兴旺    时间: 2014-4-15 22:33
1,add方法的参数类型是Object。以便于接收任意类型对象。
所以32行处,实质是
Object obj = new Person("lisi01",30);  
al.add(obj);
所以是被提升了。add中不是Person类了,识别不来getName( ),getAge()方法。

2,在多态中遵循编译看左边,运行看右边(非静态方法哦,详看毕老师基础视频第8天第5讲多态中成员方法的特点)
所以在编译时,要看看Object这个上帝类中是否有getName(),getAge()方法,发现没有当然要报错了。:P:victory:

作者: 轻语。    时间: 2014-4-15 22:37
曹冬明 发表于 2014-4-15 22:17
37行我帮你加注释教你怎么改了!不过估计你可能还没有学到泛型。iterator里存的是Object类型对象的引用,你 ...

3Q。 看泛型去。。。
作者: 轻语。    时间: 2014-4-15 22:39
香菜病病患 发表于 2014-4-15 22:28
boolean add(element e);
void add(int index,element e);
这两个是重载的应用而不是多态的应用。

我知道不是多态。 al.add(new Person("lisi01",30));
这句没有索引,所以用的是第一个方法吗?是的话那个布尔类型的返回值怎么理解?
作者: 轻语。    时间: 2014-4-15 22:40
满兴旺 发表于 2014-4-15 22:33
1,add方法的参数类型是Object。以便于接收任意类型对象。
所以32行处,实质是
Object obj = new Person(" ...

谢谢那句:多态中遵循编译看左边,运行看右边。
嘿嘿。
作者: 满兴旺    时间: 2014-4-15 22:42
伍叶竹 发表于 2014-4-15 22:40
谢谢那句:多态中遵循编译看左边,运行看右边。
嘿嘿。

不谢。。。:)
作者: 香菜病病患    时间: 2014-4-15 22:45
伍叶竹 发表于 2014-4-15 22:39
我知道不是多态。 al.add(new Person("lisi01",30));
这句没有索引,所以用的是第一个方法吗?是的话那 ...

对的,你调用的是第一个方法。那个布尔类型的返回值是用来表示是否成功将元素添加进去了。这个方法其实是定义在collection接口中的。由于List集合允许存储相同的元素,所以你可能没感觉到这个返回值的作用。但当你学Set集合时就知道这个返回值有什么用了。在Set集合中,调用该方法添加元素返回false时,证明该集合中已经有了这个元素了,所以就不存进去了。
作者: 轻语。    时间: 2014-4-15 22:48
香菜病病患 发表于 2014-4-15 22:45
对的,你调用的是第一个方法。那个布尔类型的返回值是用来表示是否成功将元素添加进去了。这个方法其实是 ...

3Q~~~~ !~~~~~~(凑齐十个字符)




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2