多態的應用
方法: 返回值類型 參數列表 方法名安全
多態的兩種實現方式
- 使用父類做爲方法形參實現多態
- 使用父類做爲方法返回值實現多態
當這個做爲參數的父類是普通類或者抽象類時,構成繼承多態 當這個做爲參數的父類是一個接口時,構成接口多態jvm
多態做爲形參(形式參數)
基本類型
知足類型轉換的規則ide
引用類型
普通類
當一個形參但願咱們傳入的是一個普通類時,咱們實際上傳入的是該類的對象/匿名對象函數
抽象類
當一個形參但願咱們傳入的是一個抽象類時,咱們實際上傳入的是該類的子類對象/子類匿名對象spa
接口
當一個形參但願咱們傳入的是一個接口時,咱們實際上傳入的是該類的實現類對象/實現類匿名對象code
多態做爲返回值
返回值類型對象
基本類型
引用類型
普通類
當一個方法的返回值是一個普通的類時,實際上返回的是該類的對象,咱們能夠使用該類的對象接收繼承
抽象類
當一個方法的返回值是一個抽象類時,實際上返回的是該抽象類的子類對象,咱們能夠使用該抽象類接收接口
接口
當一個方法的返回值是一個接口時,實際上返回的是該接口的實現類對象,咱們能夠使用接口接收io
當方法的返回值類型是引用類型的時候,能夠使用鏈式調用
注意: 當一個方法的形參是引用類型的時候,建議養成一個好的習慣: 作非空判斷
public class ArgsDemo01 { public static void main(String[] args) { // 需求: 訪問學生類中的 study方法 Student s = new Student(); s.study(); new Student().study(); // 需求: 訪問StudentDemo中的method方法 StudentDemo sd = new StudentDemo(); // sd.method(null); // 當一個形參但願咱們傳入的是一個普通類時,咱們實際上傳入的是該類的對象/匿名對象 // 習慣: 在寫方法的時候,若是方法的形參是引用類型,記住要作非空判斷,提升程序的安全性 new StudentDemo().method(new Student() { @Override public void study() { System.out.println("Student 子類 study"); } }); } } class Student { public void study() { System.out.println("Student.study()"); } } class StudentDemo { // Student s = null; public void method(Student s) { // Student s = new Student(); // if (s != null) { // s.study(); // } if (s == null) { throw new NullPointerException("對象不可以爲null"); } s.study(); } }
實例化對象加載順序
一旦實例化一個對象,其執行順序,首先:
在不涉及繼承的前提下,當首次加載類時,按照以下順序執行:
- 按照出現順序前後執行靜態成員變量定義與靜態塊;
- 按照出現順序前後執行動態成員變量定義與動態塊;
- 執行構造函數; 再次實例化對象時只執行第二、4步便可;
在涉及到繼承時,按照以下順序執行:
- 執行父類的靜態成員變量定義與靜態塊,執行子類的靜態成員變量與靜態塊
- 執行父類非靜態成員變量定義與動態塊,執行父類構造方法;
- 執行子類的非靜態成員變量定義與動態塊,執行子類構造方法;
- 注意:父類構造方法中用到的方法若是已被子類重寫,那麼在構造子類對象時在調用父類構造函數中使用子類重寫的方法。
在類加載機制中,更加詳細講解到實例化對象加載機制須要結合jvm內部運行機制的解析一塊兒分析。