14.多態

1.繼承

上一片筆記中已經寫了很多多態的東西,因爲繼承是多態的基礎

2.多態

面向對象的三個特徵:1.抽象、2.繼承、3.多態

2.1 多態

我的理解,歡迎討論

多態(Polymorphism)按字面的意思就是"多種狀態",在運行的時候會根據傳入的參數,做出不同的動作。

1.在JAVA中,接口中函數的可以有多種不同的實現方式,某個函數使用該接口作爲參數的時候,在運行時根據具體的類型,決定調用哪一個實現類的同名函數

2.JAVA中還可以通過重寫父類的方法實現多臺,使用父類的引用指向子類的對象,對象會向上轉型,通過引用調用該重寫的函數,會調用子類的函數

2.2 向上轉型

 使用父類或者接口的引用指向子類的對象

class Father{
        public int num=10;
        public void f(){
              System.out.println("1");
        }  
}

class Son extends Father{
        public int num=20;
        public void f(){
              System.out.println("2");
        }
        
        public void display(){}
}

public class Main{
      public static void main(String[] args){
  
    Father father=new Son();//向上轉型
    System.out.println(father.num);
    father.f();
    father.g();
    } 
}

 說明:

1.father對象會向上轉型,也就是說father引用調用不了函數display了

2.father.num//結果10,因爲屬性不存在動態綁定

3.father.f()//結果2,多態的緣故,調用的是子類的函數

4.father.g()//結果1,動態綁定不支持static函數,對象引用調用靜態函數的方式特別的不好。

2.3 動態綁定

Java中的函數綁定

  • 方法調用與方法主體之間的關聯關係
  • eg:Instrument類 play()函數
  •       Wind、Brass都是Instrument的子類,都對父類的play()進行了覆蓋
  •       有一個函數public void tune(Instrument instrument){instrument.play();}
  • 1.前期綁定:編譯時就知道調用哪個函數體
  • 2.後期綁定:編譯器不知道instrument對象調用的是哪個對象的play函數,運行時確定
  • Java中的函數綁定:
  • 除了static、final、private修飾的函數是前期綁定之外,所有的函數都是後期綁定
  • 所以傳入函數的參數最好都是基類的對象

2.4 動態連接

Java的類加載過程分爲以下的七個步驟

  • 加載、驗證、準備、解析、初始化、使用、卸載

  • 其中驗證、準備、解析稱爲java的連接過程、這幾個過程並不是順序進行的,其中Java的解析過程可以發生在初始化之前、也可以發生在初始化之後,這是爲了支持Java的動態綁定機制
  • 解析其其實把Java的符號引用轉換爲直接引用的過程,直接引用可以確定具體調用的函數

      • 符號引用:位於常量池的Constant_Class_info,Constant_Filed_info,Constant_Methodref_info中,通過其中的索引可以找到常量表中對應的類、方法、字段信息
      • 直接引用:目標對象的指針,或者說是操作句柄,與內存的佈局相關,一般一個符號引用解析出來的直接引用一般是不一樣的,一個對象有直接引用說明它已經存在於內存中了


2.5 動態加載

類加載

類加載器加載類的順序如下:
1、檢查這個類是否已經被加載。
2、如果沒有被加載,則首先調用父加載器加載。
3、如果父加載器不能加載這個類,則嘗試加載這個類。


動態類加載--運行時加載類

動態加載一個類十分簡單。你要做的就是獲取一個類加載器然後調用它的loadClass()方法。下面是個例子:

public class MainClass {

  public static void main(String[] args){

    ClassLoader classLoader = MainClass.class.getClassLoader();

    try {
        Class aClass = classLoader.loadClass("com.jenkov.MyClass");
        System.out.println("aClass.getName() = " + aClass.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}



參考文獻:

[1].http://blog.csdn.net/sureyonder/article/details/5569617

[2].http://ifeve.com/dynamic-class-loading-reloading/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章