Java多态的理解

北城以北 提交于 2021-02-18 08:00:24

什么是多态


  • 面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。


  • 多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)。


  • 实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。


  • 多态的作用:消除类型之间的耦合关系。


  • 现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。


  • 多态存在的三个必要条件 1、要有继承;2、要有重写;3、父类引用指向子类对象。



上菜

public class A {
public String show(D obj) { //方法一 return ("A and D"); }
public String show(A obj) { //方法二 return ("A and A"); }
static class B extends A {
public String show(B obj) { //方法三 return ("B and B"); }
public String show(A obj) { //方法四 return ("B and A"); } }
static class C extends B {
}
static class D extends B {
}

public static void main(String[] args) { A a2 = new B();
A a1 = new A(); B b = new B(); C c = new C(); D d = new D();
System.out.println("1--" + a1.show(b)); System.out.println("2--" + a1.show(c)); System.out.println("3--" + a1.show(d));
// 创建了B对象 类型是A ,调用超类函数,子类重写了 调用子类的 System.out.println("4--" + a2.show(b)); System.out.println("5--" + a2.show(c)); System.out.println("6--" + a2.show(d));
// 子类没有 去找超类 System.out.println("7--" + b.show(b)); System.out.println("8--" + b.show(c)); System.out.println("9--" + b.show(d)); System.out.println("10--" + d.show(d));
    }}

实验结果

1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D

10--A and D



让我们分析一下,理清其中各个类的继承关系




  • 那我们开始分析输出A a1 = new A();这是普通的创建对象,故a1拥有调用方法一和方法二的能力。那么究竟调用哪个方法呢,这里面涉及方法的重载。其实,在编译的时候,编译器已经进行了前期绑定,即把show();方法与类中的方法主体2进行绑定。就是说,在编译时,系统就已经知道应该调用哪个方法,即使你有方法的重载。


  • 故 a1.show(b)会与方法二绑定;a1.show(c)会与方法二绑定;a1.show(d)会与方法一绑定。且都在编译时完成绑定。


  • 但A a2 = new B();就涉及了多态 了,B实现了向上转型。创建了一个父类引用,指向子类对象。这样的做法很常见,因为这样不仅增加了灵活性(父类引用可以随时指向任意子类对象),也提高了扩展性。但要知道的是,向上转型的缺点,就是不能调用子类中有而父类没有的方法


  • 故A a2 = new B();中,方法四对方法二进行了重写,所以a2拥有调用方法一和方法四的能力,而方法三不能调用(由上一段可知)。所以,在编译时, a2.show(b)会与方法四绑定;a2.show(c)会与方法四绑定;a2.show(d)会与方法一绑定。


  • B b = new B();这是普通的创建子类对象,B继承于A,且方法四重写了方法二,所以b拥有调用方法一,方法三,方法四的能力。所以b.show(b)会与方法三绑定,b.show(c)会与方法三绑定,b.show(d)会与方法一绑定。




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

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


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


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


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


多态还可以用来做类型约束,编译器就可以确定对象类型,避免类型转换异常



本文分享自微信公众号 - Android架构师成长之路(gh_07f996f00d9b)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!