小知识,大挑战!本文正在参与“ 程序员必备小知识 ”创作活动
写在前边
- 大二上,也许恍惚间就要到面试时期了,感觉也得断断续续来拾起一些面筋。这期是“聊聊Java”系列的多态篇
作为Java三大特性之一的老大哥,为何能有他的一席之地?
实例
父类 变量名 = new 子类();
- 在接口,普通类,抽象类中都存在
设计的妙处
在编译时,我们并不知道我们最终要用的是哪个对象,比如一个Person父类,其下有Children,Adult等子类
- 我们定义一个Person person = new XXX(); 得等到运行时,我们才知道这个person具体是指向(引用)了哪个类,能访问哪些方法
- 这样,我们只需要设计好Person这个接口,当以后有新的子类时,我们只需要改变XXX,而不需要修改Person,就可以让这个person变量指向各种不同的类上,随之可以调用各种不同的子类方法,大大提高了程序的可扩展性
多态成员的特点
多态成员变量
当子父类中出现同名的成员变量时,多态调用该变量时
编译时期
参考的是引用型变量所属的类中是否有被调用的成员变量。没有,编译失败。
运行时期
也是调用引用型变量所属的类中的成员变量。
简而言之
- 编译和运行都看等号的左边。
多态成员方法
编译时期
参考引用变量所属的类,如果没有类中没有调用的方法,编译失败。
运行时期
参考引用变量所指的对象所属的类,并运行对象所属类中的成员方法。
简而言之
- 编译看左边,运行看右边
向上转型
我们上边所出现过的例子 父类 变量名 = 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多态的动态绑定。
注意
- 子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有。
向下转型
子类 变量名 = new 父类();
建议我们强转
-
Goku goku= (Goku) new SuperSaiyan();
这里向下转型是为了干什么呢,比如说我们现在的goku子类习得了新技能super4,变身超级赛亚人4
但是并不是所有的SuperSaiyan都有这般技艺阿,只有特定的子类中才有
- 现在我们要访问子类中特有的方法(非重写父类的方法),就必须向下转型才能访问到
当进行向下转型时,可以先使用** instance of **关键字进行判断,判断合法时再进行转换
多态的优缺点
优点
- 可以提高可维护性(多态前提所保证的),提高代码的可扩展性
在设计模式中可以很好的体会到多态所带来的易扩展性,后续我们也会举一些例子来更好说明
缺点
- 无法直接访问子类特有的成员和变量,就是上边所说的编译看
写在最后
- 本专栏还会断断续续更新一些Java基础知识和面经,提前为以后面试打下基础!
关于多态在设计模式中的作用,之后的文章会有所涉及到。运用到了,才能更好的体现出多态思想之妙处。