java多态的理解
一、多态是什么
面向对象的三大特性是封装、继承、多态。
多态(polymorphic)的定义:父类引用变量可以指向子类对象,允许不同类的对象可以调用同一个方法,即同一个方法可以根据调用对象的不同而有不同的实现形式。
实现多态的技术是动态绑定(dynamic binding),是指在方法的执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
多态的作用:消除类型之间的耦合关系。
现实中,关于多态的例子有很多。比方说按下 ctrl+F 键这个动作,如果当前在如果当前在 Word 下弹出的就是 Word 的查找和替换功能;在 vscode中弹出的就是 vscode的查找和替换功能。同一个事件在不同的对象中被执行会产生不同的结果。
二、多态存在的三个必要条件
1. 继承;
2. 重写;
3. 父类引用指向子类对象。
三、多态的特性
可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。
接口性(interface-ability)。多态是父类通过方法签名,向子类提供了一个共同接口,由子类来完成或者覆盖它而实现的。比如说定义一个父类Shape,规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,就可以完成或者覆盖这两个接口方法。
四、练习题
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Father a1 = new Father(); Father a2 = new Son(); Son b = new Son(); Grandson1 c = new Grandson1(); Grandson2 d = new Grandson2(); System.out.println(a1.show(a2)); // It's Father and Father System.out.println(a1.show(b)); // It's Father and Father System.out.println(a1.show(c)); // It's Father and Father System.out.println(a1.show(d)); // It's Father and Grandson2 System.out.println(a2.show(a1)); // It's Son and Father System.out.println(a2.show(b)); // It's Son and Father System.out.println(a2.show(c)); // It's Son and Father System.out.println(a2.show(d)); // It's Father and Grandson2 System.out.println(b.show(b)); // It's Son and Son System.out.println(b.show(a1)); // It's Son and Father System.out.println(b.show(a2)); // It's Son and Father System.out.println(b.show(c)); // It's Son and Son System.out.println(b.show(d)); // It's Father and Grandson2 } } class Father { public String show(Grandson2 obj){ return ("It's Father and Grandson2"); } public String show(Father obj){ return ("It's Father and Father"); } } class Son extends Father{ public String show(Son obj){ return ("It's Son and Son"); } public String show(Father obj){ return ("It's Son and Father"); } } class Grandson1 extends Son{} class Grandson2 extends Son{}
解析:
a1和a2被定义为Father类,可以使用Father类的show(Grandson2)和show(Father)两个方法;其中,a2是多态实现的,也可以使用Son类的show(Son)和show(Father)方法,并且重写了Father类的show(Father)方法;b是Son类,继承了Father类,可以使用Father类的show(Grandson2)和show(Father)两个方法以及Son类的show(Son)和show(Father)方法,并且重写了Father类的show(Father)方法
五、补充
向上转型(upcasting):一个Son类型的新对象的方法被Father对象重载使用
Father father=new Son(); father.show();//此时的show()方法是重载Son类的方法
注意:
1. 向上转型不要强制转型(int intNum=(int) doubleNum;为强制转型)
2. 向上转型后父类引用不能调用子类自己的方法
向下转型(downcasting):一个原本是Son类的对象被赋值给了Father类的对象,后又强制转型为Son类对象,转型后可以访问原本属于Son类的所有方法,因为它原本就是Son类的方法
Son son=new Son(); Father father=son; son=(Son)father;