动态绑定是java面向对象中非常重要的思想,很多java程序员不太清楚多态机制, 无疑会导致对多态理解程度不够,下面通过代码以及
在内存中的执行过程来分析动态绑定,如有错误不当之处,请读者指正!
上面的简单代码相信很多朋友似曾相识,或者说很明白的看清代码意思。
首先我们还是从程序的开始类主函数分析:(关于比较细节的描述,请看之前写过的一篇文章: http://blog.itpub.net/29876893/viewspace-1816246/,这里不作过细分析)
a1.首先在栈中放入一Cat类型的局部变量c,然后在堆中new出一Cat类型的对象内存,其中内存大致分为两部分,A部分是父类Animal对象,其中有成员变量,该例name被赋值为catname,B部分是自己的成员变量 eyesColor,被赋值为blue,然后栈中的Cat引用c指向堆中new出的Cat实例的全部
a2.在栈中放入Lady的引用ll,然后在堆中new出一Lady类型的对象内存,其中成员变量name被赋值为ll,成员变量pet被c赋值,也就是此时pet和c同时指向堆中的同一Cat实例,但是pet是Animal的引用,而Cat继承自Animal,所以此时pet指向的是普通的Animal堆内存,也就是A
a3.此时用ll调用 myPetEnjoy ( ),然后pet此时又调用 enjoy ( ) ,此时你也会想,pet到底调用哪个enjoy?由于方法是放在代码区,此时代码区有Animal的enjoy方法代码段,和Cat的enjoy方法代码段。在A中有Animalenjoy方法的指针C指向代码区中的Animal的enjoy方法代码段,由于动态绑定机制(程序运行期间),new出谁的对象,那么C就指向被该对象重写的方法,此时C指向了Cat的enjoy方法代码段,这就是动态绑定。
同理b1,b2,b3分析如上。
那么动态绑定(多态)给我们带来什么好处呢?使得程序的可扩展性达到了极致,如果上面Lady养了更多的宠物,那么只需要加上所养宠物的类(添加属性和方法),而Lady类不需要做任何的改变。
更多的动态绑定机制可以参考《thinking in java》
由于不能画出整个过程,叙述难免空洞,感兴趣的读者可以画图,会变的一目了然。
点击(此处)折叠或打开
- public class Animal {
-
- private String name;
-
- Animal(String name){
-
- this.name = name;
- }
-
- public void enjoy(){
-
- System.out.println("叫声...");
- }
- }
-
- public class Cat extends Animal {
-
- private String eyesColor;
-
- Cat(String n,String c){
-
- super(n);
- eyesColor = c;
- }
-
- public void enjoy(){
-
- System.out.println("猫叫声...");
- }
- }
-
-
- public class Dog extends Animal{
-
- private String furColor;
-
- Dog(String n,String c){
-
- super(n);
- furColor = c;
- }
-
- public void enjoy(){
-
- System.out.println("狗叫声。。。");
- }
- }
-
- public class Lady {
-
- private String name;
- private Animal pet;
-
- Lady(String name,Animal pet){
-
- this.name = name;
- this.pet = pet;
- }
- public void myPetEnjoy(){
-
- pet.enjoy();
- }
- }
-
- public class Test {
-
- public static void main(String[] args){
-
- Cat c = new Cat("catname", "bule"); //a1
- Dog d = new Dog("dogname", "black"); //b1
- Lady ll = new Lady("ll", c); //a2
- Lady l2 = new Lady("12", d); //b2
- ll.myPetEnjoy(); //a3
- l2.myPetEnjoy(); //b3
- }
- }
首先我们还是从程序的开始类主函数分析:(关于比较细节的描述,请看之前写过的一篇文章: http://blog.itpub.net/29876893/viewspace-1816246/,这里不作过细分析)
a1.首先在栈中放入一Cat类型的局部变量c,然后在堆中new出一Cat类型的对象内存,其中内存大致分为两部分,A部分是父类Animal对象,其中有成员变量,该例name被赋值为catname,B部分是自己的成员变量 eyesColor,被赋值为blue,然后栈中的Cat引用c指向堆中new出的Cat实例的全部
a2.在栈中放入Lady的引用ll,然后在堆中new出一Lady类型的对象内存,其中成员变量name被赋值为ll,成员变量pet被c赋值,也就是此时pet和c同时指向堆中的同一Cat实例,但是pet是Animal的引用,而Cat继承自Animal,所以此时pet指向的是普通的Animal堆内存,也就是A
a3.此时用ll调用 myPetEnjoy ( ),然后pet此时又调用 enjoy ( ) ,此时你也会想,pet到底调用哪个enjoy?由于方法是放在代码区,此时代码区有Animal的enjoy方法代码段,和Cat的enjoy方法代码段。在A中有Animalenjoy方法的指针C指向代码区中的Animal的enjoy方法代码段,由于动态绑定机制(程序运行期间),new出谁的对象,那么C就指向被该对象重写的方法,此时C指向了Cat的enjoy方法代码段,这就是动态绑定。
同理b1,b2,b3分析如上。
那么动态绑定(多态)给我们带来什么好处呢?使得程序的可扩展性达到了极致,如果上面Lady养了更多的宠物,那么只需要加上所养宠物的类(添加属性和方法),而Lady类不需要做任何的改变。
更多的动态绑定机制可以参考《thinking in java》
由于不能画出整个过程,叙述难免空洞,感兴趣的读者可以画图,会变的一目了然。