【聊聊Java】多态-Java三大特性之一的老大哥

564 阅读4分钟

小知识,大挑战!本文正在参与“  程序员必备小知识  ”创作活动

写在前边

  • 大二上,也许恍惚间就要到面试时期了,感觉也得断断续续来拾起一些面筋。这期是“聊聊Java”系列的多态

作为Java三大特性之一的老大哥,为何能有他的一席之地?

实例

父类 变量名 = new 子类();

  • 在接口,普通类,抽象类中都存在

设计的妙处

在编译时,我们并不知道我们最终要用的是哪个对象,比如一个Person父类,其下有Children,Adult等子类

  • 我们定义一个Person person = new XXX(); 得等到运行时,我们才知道这个person具体是指向(引用)了哪个类,能访问哪些方法
    • 这样,我们只需要设计好Person这个接口,当以后有新的子类时,我们只需要改变XXX,而不需要修改Person,就可以让这个person变量指向各种不同的类上,随之可以调用各种不同的子类方法,大大提高了程序的可扩展性

多态成员的特点

多态成员变量

当子父类中出现同名的成员变量时,多态调用该变量时

编译时期

参考的是引用型变量所属的类中是否有被调用的成员变量。没有,编译失败。

运行时期

也是调用引用型变量所属的类中的成员变量。

简而言之

  • 编译和运行都看等号的左边。

多态成员方法

编译时期

参考引用变量所属的类,如果没有类中没有调用的方法,编译失败。

运行时期

参考引用变量所指的对象所属的类,并运行对象所属类中的成员方法。

简而言之

  • 编译看左边,运行看右边

向上转型

image.png 我们上边所出现过的例子 父类 变量名 = new 子类(); 即图中的 Animal a1 = new Cat(); 我们定义出来的类型是Animal父类,但用的是子类Cat的new构造方法,实际上这里会将我们的子类型向上转型为父类型

静态绑定

编译看左边

Animal a1 = new Cat(); 程序在编译阶段,animal引用类型被编译器看做Animal类型,所以程序在编译阶段,animal引用绑定的是Aninmal类中的shout()方法,这个过程叫做Java多态的静态绑定

动态绑定

运行看右边

程序在运行的时候,堆中的对象实际上是Cat类型,而Cat对象已经覆盖(重写)了父类Animal的shout()方法,所以程序在运行阶段,对象绑定的方法是Cat中的shout()方法,这个过程叫做Java多态的动态绑定

注意

  1. 子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有

向下转型

子类 变量名 = new 父类();

image.png

建议我们强转

image.png

  • Goku goku= (Goku) new SuperSaiyan();

这里向下转型是为了干什么呢,比如说我们现在的goku子类习得了新技能super4,变身超级赛亚人4 image.png 但是并不是所有的SuperSaiyan都有这般技艺阿,只有特定的子类中才有

  • 现在我们要访问子类中特有的方法(非重写父类的方法),就必须向下转型才能访问到

当进行向下转型时,可以先使用** instance of **关键字进行判断,判断合法时再进行转换

多态的优缺点

优点

  • 可以提高可维护性(多态前提所保证的),提高代码的可扩展性

在设计模式中可以很好的体会到多态所带来的易扩展性,后续我们也会举一些例子来更好说明

缺点

  • 无法直接访问子类特有的成员和变量,就是上边所说的编译看

写在最后

  • 本专栏还会断断续续更新一些Java基础知识和面经,提前为以后面试打下基础!

关于多态在设计模式中的作用,之后的文章会有所涉及到。运用到了,才能更好的体现出多态思想之妙处。