之前忘了在哪看到一篇文章了。当时不是没细看,是根本没看。。。。 java变量有两种类型,一种是声明类型,一种是实际类型。 如 Person p = new Student(); Person 是声明类型,Student是实际类型。 p只能调用声明类型(Person)的方法和属性。Student特有的属性和方法被隐藏(隐藏,不是消失) 但因为它实际类型是Student。所以,调用p的方法时,会去检查Student里有没有该方法,有的话,。。。 ==================================== 我来说说我的理解(不知道对不对):编译期和运行期 1、在编译期,声明类型起作用。p声明为Person类型,所以编译的时候,会检查p调用的属性,方法是不是p的,如果Person中不存在,报错。 2、运行期,实际类型起作用。因为p的实际类型是Student。编译成class时的时候,p已经变成Student类型了。所以执行p.print打印的是student。 学习时往往会有先入为主的现象。当听到一种观点,而自己又赞成的时候,不管它是对是错,都会给自己带来深刻的印象和影响。 我希望我的观点不会给你带来困扰(假如我的理解不对的话)
赞同,我的总结和你所看的书以及你自己的理解大同小异。 多态是发生在运行期间。。。 产生多态的条件是:①发生继承关系②子类重写父类方法③父类引用指向子类对象; Person p = new Student();这个时候的new出来的具体的Student对象在实际程序当中,在p引用变量的眼里,它只看到了Student对象中的Person类,所以,p是不可以调用所new出对象的新增加的成员变量或方法,比如不能p.ID;由于print()这个方法在父类和子类中都存在,发生了重写,所有已经满足多态条件,在通过p.print()这个方法的时候,Student实际对象中的Person类中指向code segment的实际Person类print方法的指针(可能不太准确),动态的指向了Student类的print()方法,(根据p所指向的实际对象所属的类型判定,所以使用重写的方法),如果子类没有重写父类print(),p.print()则调用的是父类的print()方法,打印为Person(虽然我还没试) 关于Person p = new Student()关于这句话引申: p只是一个引用而已,并不是具体的实际的对象,只不过在学习过程中,为了方便等某些原因,就直接把这个引用p,说成是对象,很多人一直以为p就是对象,其实他只是一个指向实际对象的引用而已,真正的对象是new出来放在heap中的,当你直接System.out.println(p);那实际上打印出来的是一个:类名+@+hashcode的字符串(默认继承了java.lang.Object,所以继承下来了toString()方法,打印p的时候,自动变成了p.toString()),把p理解为指向对象的一个引用,他具备一个找到对象在内存中位置的地址;