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

  1. <font size="1">class Person
  2. {
  3.    String name;
  4.    Person(String name)
  5.    {
  6.       this.name = name;
  7.    }
  8.    //...
  9. }
  10. //定义一个子类Student
  11. class Student extends Person
  12. {
  13.    String name;
  14.    private int id;
  15.         Student(String name,int id)
  16.         {
  17.                 super(name);
  18.                 this.id = id;
  19.         }
  20.         public int getId()
  21.         {
  22.                 return id;
  23.         }
  24.         public void setId(int id)
  25.         {
  26.                 this.id = id;
  27.         }

  28. }
  29. class DuotaiDemo
  30. {
  31.         public static void main(String[] args)
  32.         {
  33.                 //第一个
  34.                 Person p = new Person("小明");
  35.                 p = null;
  36.                 System.out.println(p);
  37.                 //----------------------
  38.                 //第二个
  39.                 //Person变量可以引用Person的对象,也可以引用它的子类对象
  40.                 Student stu = new Student("大明",0001);
  41.                 Person[] per = new Person[10];
  42.                 per[0] = stu;
  43.                 //第三个
  44.                 Student[] student = new Student[2];
  45.                 //将student转换成Person[]是合法的
  46.                 Person[] person = student;
  47.                 person[0] = new Person("小黑");//给person[0]赋Person类型的值
  48.                 student[0].setId(0002);
  49.                 System.out.println(student[0].name + "的id是" + student[0].getId());
  50.         }
  51. }</font>
复制代码
对于第一个:
将p = null,是p不再指向new出的“小明”这个对象了呢?还是说new出的这个“小明”也随之在内存中消亡了呢?还是说要等内存自动在某个时候消亡呢?
对于第二个:
我们说多态是表示事物的多种形态,那么,这里的多种形态,是不是不能同时具备呢?
上面的代码中,per[0] = stu后,它们引用的是同一个对象,是("大明",0001)这个对象,那么是不是Per[0]就不在指向new Person[10]其中的第一个对象(虽然为null)了呢?
对于第三个:
Person[] person = student;这个语句中,应该是指向的同一个类型的数组(应该是Person[]这个数组吧?),那么现在,student是Student[]数组的类型呢?还是Person[]数组的类型呢?
1、如果是Student[]数组的类型,那么下面的student[0].setId(0002);这个方法是没错的,但是就不是和Person[0]指向相同数组了,

是不是这时候已经将Person[] person = student;这句的行为覆盖掉了呢?
2、如果是Person[]数组的类型,那么下面的student[0].setId(0002);这个方法是不成立的,因为编译时虽然可以通过,但是运行后会报错,如下:

希望大家能帮忙解答清晰。


多态测试.png (5.08 KB, 下载次数: 75)

多态测试.png

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1

查看全部评分

45 个回复

正序浏览
王昕 发表于 2013-2-8 00:05
引用这个叫法,也不是太好,因为“引用”说话的时候经常会用到,也许真的是引用的意思而不是reference,所 ...

嗯,或许这怎么说是不太好,但是既然是公认叫法,就只能这样了。
回复 使用道具 举报
引用这个叫法,也不是太好,因为“引用”说话的时候经常会用到,也许真的是引用的意思而不是reference,所以有翻译叫“句柄”。
回复 使用道具 举报
黄玉昆 发表于 2013-2-7 23:48
忘了给你文章地址了:http://blog.csdn.net/wangkr111/article/details/7830079

2:空指针异常发生在对象为空,但是引用这个对象的方法。例如: String s = null; //对象s为空(null) int length = s.length();//发生空指针异常

3:一个变量是null,及只有其名,没有实值内容,也没分配内存,当你要去取他的长度,对他进行操作就会出现NullPointException,所以生命一个变量时最好给它分配好内存空间,给予赋值。

这个人可能是先学的C++习惯了C++的说法。String s;他管 s 叫对象严格来说不合适。
他的3,其实就是说,一个引用是null,他说“只有其名”,就是说只有引用,“没有实质内容,也没分配内存”,就说没有new出来一个对象,他说“声明一个变量最好给它分配好内存空间”,就说让你声明的时候就new出来,不要只声明一个引用类型,而不给它new一个对象。
他写博客用词不会抠那么仔细,你看都有错别字,声明写成了“生命”。
对于老手管引用叫对象无所谓,他心里知道就行了,新手真的会以为是个对象。
可能你是觉得String s = "abc";没有new也有对象,所以 s 是对象,这句其实是String s = new String("abc");
回复 使用道具 举报
黄玉昆 发表于 2013-2-7 23:48
忘了给你文章地址了:http://blog.csdn.net/wangkr111/article/details/7830079

Head first Java 60页,就是讲建Dog数组对象和建Dog对象。百度文库一搜就有的。
http://wenku.baidu.com/view/4b0ff1d8d15abe23482f4d8a.html
回复 使用道具 举报
王昕 发表于 2013-2-7 23:46
他其实想表达的意思是:“空指针异常发生在reference为null,但是用这个引用调用对象的方法。”
有时候翻 ...

忘了给你文章地址了:http://blog.csdn.net/wangkr111/article/details/7830079
回复 使用道具 举报
本帖最后由 王昕 于 2013-2-7 23:49 编辑
黄玉昆 发表于 2013-2-7 23:23
你可以看看我新改的代码。结果会返回一个错误,是空指针异常,但是这个错我,我看了相关的文章,说是“空 ...


他其实想表达的意思是:“空指针异常发生在reference为null,但是用这个引用调用对象的方法。”
有时候翻译的人不分对象和引用,把reference翻译成对象,很容易误导人,因为C++里面Student s;这种语句就说成定义Student类型的对象s,但是Java还是说对象引用s,或者说引用s。
Java核心技术卷I是京京工作室翻译的,翻译毁了,卷II翻译的比较好。
包括Head first Java,中文版翻译的也是不大行,所以得有个英文的对着看。中文的百度文库有,英文的csdn有。
回复 使用道具 举报
王昕 发表于 2013-2-7 22:47
嗯,畅销书还是比较权威的吧……你看看Head first Java第三章还是第四章记不清了,就知道了,还有后面多 ...

嗯啊,你说的挺对的,不过你也可以看看java核心技术,里面关于对象中继承那部分,有关多态的知识。资料我分享在了帖子里,希望能对你有帮助。
资料:http://bbs.itheima.com/thread-37948-1-1.html
回复 使用道具 举报
王昕 发表于 2013-2-7 21:53
如果Person[] person = new Student[10]是对的,那么你打算给person[0]装什么东西呢?如果Person还有别的 ...

你可以看看我新改的代码。结果会返回一个错误,是空指针异常,但是这个错我,我看了相关的文章,说是“空指针异常发生在对象为空,但是引用这个对象的方法。”。这说明,还是有对象存在的,只不过为空。
代码如下:
  1. class Demo0
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Student[] s = new Student[10];
  6.                 for (int i=0;i<s.length;i++)
  7.                 {
  8.                         s[i].name = (String)("a " + i);
  9.                         s[i].setId(i);
  10.                         System.out.println(s[i].name + "的ID:" + s[i].getId());       
  11.                 }
  12.         }
  13. }

  14. class Student
  15. {
  16.         String name;
  17.         private int id;
  18.         Student(String name,int id)
  19.         {
  20.                 this.name = name;
  21.                 this.id = id;
  22.         }
  23.         public int getId()
  24.         {
  25.                 return id;
  26.         }
  27.         public void setId(int id)
  28.         {
  29.                 this.id = id;
  30.         }

  31. }
复制代码
回复 使用道具 举报
只能new Student
回复 使用道具 举报
朱玉玺 发表于 2013-2-7 22:40
用person的话,只能调name,不能掉id,因为这个引用看不到子类的id

有Person[] person = new Student[2];这种语句存在,并且有person[0] = new 随便();这种存在,用person[0].能输出正确的信息?
回复 使用道具 举报
黄玉昆 发表于 2013-2-7 22:37
我不是不信,既然都说服不了对方,那么就用很有权威性的证据说明一下,就行了。等我看到了相关的知识再交 ...

嗯,畅销书还是比较权威的吧……你看看Head first Java第三章还是第四章记不清了,就知道了,还有后面多态的大概七八九章吧。
不用客气,你回复我认真,我自然回复你也认真,如果你表现的对我的说法不屑,我肯定也就不理啦:lol
你回我那么多是想帮我纠正我的错误,是想帮助我,虽然关于引用这个问题我比较有把握是我对了,不过以后别的问题就另当别论了。多交流总是好的,交流无所谓谁对谁错,一起学习,交流只要真诚就好,你的回复我觉得很真诚,所以我也想帮你搞清楚。引用是个遥控器这个比喻,很多书都用,包括Thinking in Java。
回复 使用道具 举报
王昕 发表于 2013-2-7 22:37
你没用person[1]. 这种来调用对象,我认为这样用的话是会出异常的。你用的都是student[1]. 。 ...

用person的话,只能调name,不能掉id,因为这个引用看不到子类的id
回复 使用道具 举报
本帖最后由 王昕 于 2013-2-7 22:39 编辑
朱玉玺 发表于 2013-2-7 22:31
呵呵,也只有在楼主这样的实验中,一般不会出现这种情况。


你没用person[1]. 这种来调用对象,我认为这样用的话是会出异常的。你用的都是student[1]. 。
回复 使用道具 举报
王昕 发表于 2013-2-7 22:05
哥们,你好像没区分什么是对象,什么是对象的引用,引用有的翻译成句柄。
你的p是引用而不是对象,如果用 ...

我不是不信,既然都说服不了对方,那么就用很有权威性的证据说明一下,就行了。等我看到了相关的知识再交流。不过很谢谢你的回复。从你的回复中,确实学到了不少东西,十分感谢你
回复 使用道具 举报
黄玉昆 发表于 2013-2-7 22:28
不知道给你写的那个代码,你运行了没有,你运行之后就知道,我就用了一个new,但是打印了十个null ...

我知道你一个new打印十个null啊,因为你new出来了十个绑在一起的引用啊。
十个绑在一起的引用是一个数组对象。
回复 使用道具 举报
王昕 发表于 2013-2-7 22:24
我都不说编译运行有没有错的问题,那其实是不严重的问题。大家一起写程序,你写个Person[] p=new Student ...

我不是为了说明这段代码是不是有意义,只是为了把内存分配问题搞清楚。只有内存中的状态清楚了,才能更好地理解代码,更好地运行代码。尤其在数组这种特殊的对象,还有一种类型就是String,也是很特殊的,我觉得能把这两个弄清楚,就基本上把类型性的知识学透彻了。这是我的本意。
回复 使用道具 举报
王昕 发表于 2013-2-7 22:24
我都不说编译运行有没有错的问题,那其实是不严重的问题。大家一起写程序,你写个Person[] p=new Student ...

呵呵,也只有在楼主这样的实验中,一般不会出现这种情况。
回复 使用道具 举报
黄玉昆 发表于 2013-2-7 22:25
这“一大坨东西”是什么意思啊?怎么会不关null的事呢?


就是说一个Student对象有什么,得看你写类的时候给他了多少成员变量,才能知道这坨东西有什么,有多大。
而引用,就占那么多字节 ,就是个遥控器。遥控器啥也不遥控的时候就是null,有东西遥控就是那个东西的地址。null是什么?null就是一个引用的特殊值,就是没有。对象只能说对象的某个成员变量是不是null,前提是这个变量是个引用类型。
回复 使用道具 举报
王昕 发表于 2013-2-7 22:19
哥们,你基本概念有误区。
引用可以在栈也可以在堆,像Student[] stu = new Student[10]这种吧,stu在栈 ...

不知道给你写的那个代码,你运行了没有,你运行之后就知道,我就用了一个new,但是打印了十个null
  1. class Demo0
  2. {
  3.     public static void main(String[] args)
  4.    {
  5.        Person[] p = new Person[10];
  6.        for (int i=0;i<p.length;i++)
  7.        {
  8.            System.out.println(p[i]);        
  9.        }
  10.   }
  11. }
  12. class Person
  13. {
  14.      String name;
  15.      Person(String name)
  16.     {
  17.      this.name = name;
  18.     }
  19. }
复制代码
回复 使用道具 举报
123下一页
您需要登录后才可以回帖 登录 | 加入黑马