1. 多态的含义
- 面向对象的三大基本特征: 封装,继承,多态。
- 多态是干什么的?
- 多态将做什么和怎么做分离开。从另一个角度将接口是实现类分离开。
- 多态的作用
- 消除类型之间耦合的关系
- 使用多态的好处?
- 能够改善代码的组织结构,提高代码可读性
- 能够创建可扩展的程序。
2. 方法的调用
package net.mindview.polymorphism; //乐器 class Instrument { public void play(Note i){ System.out.println("Instrument.play() "); } } //风管乐器 class Wind extends Instrument { @Override public void play(Note i) { System.out.println("Wind.play() "); } } public class Music { //曲调 public static void tune(Instrument i){ i.play(Note.MIDDLE_C); } public static void main(String[] args) { Wind wind = new Wind(); tune(wind); } }
分析:这里有一个行为很特殊, 就是tune方法,他传递的参数Instrument,调用的也是Instrument的play方法,那么当我在Music中传递一个wind给tune时,他会知道我要调用的方法应该是Wind总的play方法,而不是Instrument中的方法么?是的, 可以.这个过程在前期绑定的时候肯定是不知道的, 他是在后期绑定的时候知道的.
下面来说说什么是绑定?
- 绑定的概念(可以忽略,理解后面的就可以知道他是什么含义了):将一个方法调用同一个方法的主体关联起来被称作绑定。(这时书上这么定义了, 我觉得语义不通,所以不用试图理解这句话)
- 前期绑定:程序执行前,也就是在编译器进行绑定,叫做前期绑定
- 后期绑定:又称为动态绑定, 在运行时根据对象的类型进行绑定。
- java中,除了static方法和final方法(paivate方法属于是final方法)之外,都是后期绑定
- 在讨论,为什么要将一个方法定义为final的呢?
- 之前说的原因是,为了防止方法被覆盖。也就是不允许继承的子类覆盖这个方法
- 更重要的原因是:这样做可以有效地“关闭”动态绑定。或者说,告诉编译器,不需要动态绑定。
3. 什么样的程序是可扩展的?
- 让我们回到"乐器"那个例子. 在系统中再添加多个类型的乐器, tune方法是不需要修改的. 在一个设计良好的OOP程序中, 大多数方法或者所有方法都想tune方法一样,只是与基类接口通讯, 这样的程序是可扩展的.
4. 静态方法不具有多态性. 调用的时那个对象的方法,执行的就是那个对象的方法, 不会向上转型
5.构造器调用的顺序
- 调用基类构造器, 逐级向上
- 按声明顺序调用成员的初始化方法
- 调用导出类构造器
6.忠告: 编写构造器的时候, 用尽可能简单的方法是对象进入正常状态,尽量避免调用其他方法
7.协变返回类型
package net.mindview.polymorphism; class Grain { @Override public String toString() { return "Grain"; } } class Wheat extends Grain { @Override public String toString() { return "Wheat"; } } class Mill { Grain process(){ return new Grain(); } } class WheatMill extends Mill { Wheat process(){ return new Wheat(); } } public class GovariantReturn { public static void main(String[] args) { Mill m = new Mill(); Grain g = m.process(); System.out.println(g); WheatMill w = new WheatMill(); Wheat wh = w.process(); System.out.println(wh); } }
- 看上述代码, 理解斜边类型的含义
- 在Mill中定义的process的返回类型Grain,而WheatMill继承自Mill。在WheatMill中的方法process返回的是Wheat,而Wheat是Grain的子类, 这时被允许的。
8.纯继承
- 纯继承:如果子类具有的方法全部是父类的方法,也就是说和父类一模一样,就是is-a的关系, 即纯继承
- 非纯继承:如果子类不仅包含父类方法, 还扩展的新的方法,就是is -like-a的关系