我理解的多态

来源:互联网 发布:网络直播电视 编辑:程序博客网 时间:2024/06/05 20:15
了解多态首先要了解向上转型以及前期绑定和后期绑定。参考thinking in java 第八章(都是自己理解的欢迎大家指正)
package com.compare.gc;class Father {public void play(){System.out.println("father");}}class Son extends Father{public void play(){System.out.println("son");}}public class Main{public static void tune(Father i){   i.play();}public static void main(String[] args){Son son = new Son();tune(son);}}

-----output----
son

明明tune方法的参数类型是father但是用son也可以运行这就是多态。(这里提一点,就算你把son类中的play方法注释掉,他依然会去father找play方法并成功运行)

将一个方法调用同一个方法主体关联起来叫做绑定
前期绑定就是程序在执行前进行绑定。(另外C语言中只有前期绑定)
后期绑定就是运行时根据对象的类型进行绑定。

这里用father和son类举个浅显的例子,在编译的时候Main类里面的方法tune调用i.play方法,编译器要确定这个play是在哪个类的,但是他没办法确定。因为可能是father也可能是son类里面的play方法。所以只能是后期绑定啦。

Java中除了static方法和final方法(private方法属于final方法,想了一下private的方法不能被子类继承原来是这个道理)之外,其他所有的方法都是后期绑定。
所以将方法申明为final的作用就是可以有效的避免动态绑定,让编译器为final方法调用生成有效的代码。但是对程序整体性能没多大的改观。
---------------编辑于2017/6/29---------------
今天接触到一个新问题,多态存在的3个必要条件。开始不太清楚答案,百度了一下,思考了一下。下面说一下我的理解:

Java实现多态有三个必要条件:
1.继承
2.重写
3.向上转型。(有些博客会说父类引用指向子类对象其实就是向上转型一个意思)

1.继承:没有继承就没有父类子类的关系,当然不会有多态。多态需要向上转型的关系,向上转型自然是需要继承的。
2.重写:如果不重写,我们在结果上就看不出区别。(下面重点讲一下这一项)
3.向上转型:同1

关于重写是必要条件这一项,我存有疑虑。我试着将上例子的play方法都改为System.out.println(this);
发现输出结果是com.compare.gc.Son@15db9742。虽然没有重写,但是依然进行了动态绑定。所以我觉得重写并不是必要条件。
但是还有另外一个解释,因为print的是this,this其实在每个类中都不一样,其实就算是进行了重写。
具体哪个是对的也不深究了,概念这东西,知道原理就行了,具体争哪个是对的就是文字游戏了。