多态是同一个行为具有多个不同表现形式或形态的能力
现实中,比如我们按下 F1 键这个动作:
- 如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
- 如果当前在 Word 下弹出的就是 Word 帮助;
- 在 Windows 下弹出的就是 Windows 帮助和支持。
同一个事件发生在不同的对象上会产生不同的结果。
所谓java的多态性就是:编译的时候把“子类”都当作“父类”来编译,在运行期间再由Java自己对父子进行区分然后用其对应的功能
举个通俗的例子:
张氏家族世世代代都是机械工程师,多来年口碑甚好,只接自己100%能处理的问题,但因为时代更替,技术迭代,张爷爷会的技术最少,张爸爸多一点,张儿子会的最多。
编译期就相当于有一个工厂的机器出现了一个问题,这个问题让张氏家族的任何一个人来都可以处理(张爷爷肯定会,张爸爸和张儿子肯定更会),因此工厂决定通知张爷爷让他们家随便来一个人(即具体new张爸爸对象还是new张儿子对象),他们3个人都能完成任务,只是处理的具体方式不同(方法的覆写)
Grandfather A = new Grandfather();
//第一条实例化不是多态性的体现
Grandfather B = new Father();
Grandfather C = new Son();
//B和C都是多态性的体现
创建的B和C本质是创建了张爸爸和张儿子,但由于要保证百分之百去了就能处理,张氏家族在接活的时候会声明必定能处理的问题(左边写Grandefather X = ),再考虑具体谁去做,比如”Grandfather C = new Son();“就是让孙子去做,那么孙子有孙子的方法,但孙子允许做的事必须满足“张爷爷也会”的这个大前提
class Grandfather{//张爷爷的修理方案
public void repair(){
System.out.println("用扳手和改刀修");
}
}
class Father extends Grandfather{//父承爷类
public void repair(){
System.out.println("用扳手、改刀、测量仪器修");
}
}
class Son extends Father{//子承父类
public void repair(){
System.out.println("用一体化设备修");
}
public void prevent(){
System.out.println("孙子越来越有职业道德,会提醒客户注意点");
}
}
可以看到三人对于“修理"这件事情有不同的处理方法,并且张孙子更会为客户考虑,但在编译期,上述代码创建出来的C对象坚决不能调用prevent()方法!
编译看左,运行看右:(虚拟方法调用)
Person A = new Man(); 左边决定能用什么属性or方法,右边决定用谁的属性or方法
在编译期只能调用父类中声明的方法,但在执行期实际执行的是子类重写的方法
左边父类,右边子孙:
父类引用指向子类对象,子类对象赋给父类引用,左边范围小,右边范围大
如果左边是子类,右边是父类就会报错