java中多态的前提条件,与静态绑定方法混淆

来源:互联网 发布:抢票软件收费 编辑:程序博客网 时间:2024/05/29 16:30

问题一:从最后的结果可以看出:最后运行出来的结果是父类的show()方法:为什么呢?


     因为首先多态是要在一些前提条件下,才可以体现出多态的特性,在方法上使用 动态绑定的方式表现出来。

对于多态,可以总结它为:       

     一、使用父类类型的引用指向子类的对象;

    二、该引用只能调用父类中定义的方法和变量;

    三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)

    四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。

多态的3个必要条件:

        1.继承   2.重写   3.父类引用指向子类对象。


问题二:既然了解了该实例不满足动态绑定的条件,那属于什么呢?

     类的私有方法,是属于静态绑定,是在java 编译过程已经确定下来的,及在编译过程把方法 编译成字节码invokevirtual #6 的字节,当程序运行时,直接读字节码就可以快速找到方法。提高效率。所以类的私有方法是属于类的,不能被子类重写,所以不满足动态绑定,所以属于静态绑定。


问题三:JVM虚拟机运行时,代码DEBUG出来 ——>实际对象是子类对象,子类也有这个私有方法。为什么输出的还是调用的父类的show()方法呢?


首先私有方法属于静态绑定,所以,在编译就确定好了show()方法 是调用的父类的方法。

因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特,   定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。 

    所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;   同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;   对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。也可以叫做动态绑定。

实际上就是在申明的问题上,申明了一个父类的引用,就有了父类的所有私有方法的访问权,编译时期,私有方法也能访问到。所以作用就是父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用。就是沿用了父类的方法。就算子类也有这个方法,由于静态绑定,又由于申明的是父类引用。所以在没运行之前就确定了是调用父类的方法。


——————————————————————————————————————————————————————————————————————

总结:

程序绑定的概念:
绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定.


静态绑定:
在程序执行前方法已经被绑定(也就是说在编译过程中就已经知道这个方法到底是哪个类中的方法),此时由编译器或其它连接程序实现。例如:C。
针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定


动态绑定:
后期绑定:在运行时根据具体对象的类型进行绑定。
若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。
动态绑定的过程:
虚拟机提取对象的实际类型的方法表;
虚拟机搜索方法签名;
调用方法。
1.静态绑定发生在编译时期,动态绑定发生在运行时
2.使用private或static或final修饰的变量或者方法,使用静态绑定。而虚方法(可以被子类重写的方法)则会根据运行时的对象进行动态绑定。
3.静态绑定使用类信息来完成,而动态绑定则需要使用对象信息来完成。
4.重载(Overload)的方法使用静态绑定完成,而重写(Override)的方法则使用动态绑定完成。


那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特,   定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。 


    所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;   同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;   对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。也可以叫做动态绑定。













0 0