Java中的多态对成员函数和成员变量中的调用

来源:互联网 发布:花落知多少图片 编辑:程序博客网 时间:2024/05/16 00:56

多态简单来说就是事务的多种体现形态。
一个子类A继承父类B之后, B b = new A();这就是多态
可是难题也出来了,多态了之后方法调用成为了一个问题,我学了Java半年之后对这里也是傻傻分不清楚,下面对这里进行比较总结比较

1.多态对非静态成员函数的调用

public class Animal {     public void eat(){         System.out.println("动物吃饭");     }}public class Dog extends Animal {     public void eat(){         System.out.println("狗吃骨头");     }} public static void main(String[] args) {    Animal a = new Dog();    a.eat();}

最后输出狗吃骨头,说明当非静态函数调用的时候还是调用子类的成员函数(在多态情况下也就是,Animal a = new Dog();)
然后想想如果子类有父类没有的方法 如果父类调用会怎么样所以把子类改成这样

public class Dog extends Animal {     public void eat(){         System.out.println("狗吃骨头");     }     public void look(){         System.out.println("狗看家");     }}

然后调用一下看家的方法
发现程序报错,说父类没有look方法 这是编译时期的先编译父类, 首先,编译器根据对象的声明类型和方法名,搜索相应类(Son)及其父类(Father)的“方法表”,找出所有访问属性为public的method方法。可是没有look方法 所以GG了
发现多态对非静态方法的调用还是很简单的,首先父类如果有这个方法,然后调用的时候调用子类的这个方法。
子类的方法把父类的方法给覆盖了 这个很简单 所以调用子类的方法也就是采用动态绑定

2.调用变量

 public static void main(String[] args) {    Animal a = new Dog();    System.out.println(a.a);}

我在父类中添加了一个int a=1; 子类中添加了一个int b=2;
最后输出1,说明对于变量来说是调用父类的
因为变量相当于父类的一个属性,可以用类名调用,相当于静态绑定,因为在方法运行之前就把这个变量存储在内存中了,

3.静态成员函数

public  class Animal {  int a=1;     public static void eat(){         System.out.println("动物吃饭");     }}public class Dog extends Animal {   int a=2;     public static void eat(){         System.out.println("狗吃骨头");     }     public void look(){         System.out.println("狗看家");     }}public class test { public static void main(String[] args) {    Animal a = new Dog();    a.eat();}}

最后输出动物吃饭 说明调用的父类的方法 所以得到结论说多态调用静态方法时运行父类的方法 这个调用静态绑定,

结论

多态调用非静态成员函数时
编译看父类,运行看子类
多态调用变量时 都看父类
多态调用静态函数时 看父类

static,final,private采用静态绑定,也就是在程序运行之前就已经确定调用哪个方法了 。如果方法的调用是在运行时期解析,那就是动态绑定(dynamic binding)或者延迟绑定(late binding)。
如果一个方法不可被继承或者继承后不可被覆盖,那么这个方法就采用的静态绑定。也就是说可以用类名调用这个方法或者变量的都是看父类,如果采用动态绑定也就是说只能对象调用这个方法的看子类,如果想看看关于更多动态绑定的知识可以看看这个http://blog.csdn.net/zhangjk1993/article/details/24066085
感觉写的挺不错的,可以看看