理解靜態綁定與動態綁定

一個Java 程序要通過編寫、編譯、運行三個步驟,其中編寫代碼不在咱們討論的範圍以內,那麼咱們的重點天然就放在了編譯 和 運行這兩個階段,因爲編譯和運行階段過程至關繁瑣,下面就個人理解來進行解釋:設計模式

Java程序從源文件建立到程序運行要通過兩大步驟:

一、編譯時期是由編譯器將源文件編譯成字節碼的過程ide

二、字節碼文件由Java虛擬機解釋執行ui

綁定

綁定就是一個方法的調用與調用這個方法的類鏈接在一塊兒的過程被稱爲綁定。spa

綁定分類

綁定主要分爲兩種:.net

靜態綁定 和 動態綁定設計

綁定的其餘叫法

靜態綁定 == 前期綁定 == 編譯時綁定code

動態綁定 == 後期綁定 == 運行時綁定cdn

爲了方便區分: 下面統一稱呼爲靜態綁定和動態綁定對象

靜態綁定

在程序運行前,也就是編譯時期JVM就可以肯定方法由誰調用,這種機制稱爲靜態綁定blog

識別靜態綁定的三個關鍵字以及各自的理解

若是一個方法由private、Static、final任意一個關鍵字所修飾,那麼這個方法是前期綁定的

構造方法也是前期綁定

private:private關鍵字是私有的意思,若是被private修飾的方法是沒法由本類以外的其餘類所調用的,也就是本類所特有的方法,因此也就由編譯器識別此方法是屬於哪一個類的

public class Person {

    private String talk;

    private String canTalk(){
        return talk;
    }
}

class Animal{

    public static void main(String[] args) {
        Person p = new Person();
        // private 修飾的方法是Person類獨有的,因此Animal類沒法訪問(動物原本就不能說話)
//        p.canTalk();
    }
}複製代碼

final:final修飾的方法不能被重寫,可是能夠由子類進行調用,若是將方法聲明爲final能夠有效的關閉動態綁定

public class Fruit {

    private String fruitName;

    final String eatingFruit(String name){
        System.out.println("eating " + name);
        return fruitName;
    }
}

class Apple extends Fruit{

      // 不能重寫final方法,eatingFruit方法只屬於Fruit類,Apple類沒法調用
//    String eatingFruit(String name){
//        super.eatingFruit(name);
//    }

    String eatingApple(String name){
        return super.eatingFruit(name);
    }
}複製代碼

static: static修飾的方法比較特殊,不用經過new出某個類來調用,由類名.變量名直接調用該方法,這個就很關鍵了,new 很關鍵,也能夠認爲是開啓多態的導火索,而由類名.變量名直接調用的話,此時的類名是肯定的,並不會產生多態,以下代碼:

public class SuperClass {

    public static void sayHello(){
        
        System.out.println("由 superClass 說你好");
    }
}

public class SubClass extends SuperClass{

    public static void sayHello(){
        System.out.println("由 SubClass 說你好");
    }

    public static void main(String[] args) {
        SuperClass.sayHello();
        SubClass.sayHello();
    }
}複製代碼

SubClass 繼承SuperClass 後,在file是沒法重寫sayHello方法的,也就是說sayHello()方法是對子類隱藏的,可是你能夠編寫"本身的"sayHello()方法,也就是子類SubClass 的sayHello()方法,因而可知,方法由static 關鍵詞所修飾,也是編譯時綁定

動態綁定

概念

在運行時根據具體對象的類型進行綁定

除了由private、final、static 所修飾的方法和構造方法外,JVM在運行期間決定方法由哪一個對象調用的過程稱爲動態綁定

若是把編譯、運行當作一條時間線的話,在運行前必需要進行程序的編譯過程,那麼在編譯期進行的綁定是前期綁定,在程序運行了,發生的綁定就是後期綁定

代碼理解

public class Father {

    void drinkMilk(){
        System.out.println("父親喜歡喝牛奶");
    }
}

public class Son extends Father{

    @Override
    void drinkMilk() {
        System.out.println("兒子喜歡喝牛奶");
    }

    public static void main(String[] args) {
        Father son = new Son();
        son.drinkMilk();
    }
}複製代碼

Son類繼承Father類,並重寫了父類的dringMilk()方法,在輸出結果得出的是兒子喜歡喝牛奶。那麼上面的綁定方式是什麼呢?

上面的綁定方式稱之爲動態綁定,由於在你編寫 Father son = new Son()的時候,編譯器並不知道son對象真正引用的是誰,在程序運行時期才知道,這個son是一個Father類的對象,可是卻指向了Son的引用,這種概念稱之爲多態,那麼咱們就可以整理出來多態的三個原則:

1. 繼承

2.重寫

3.父類對象指向子類引用

也就是說,在Father son = new Son() ,觸發了動態綁定機制。

動態綁定的過程

  1. 虛擬機提取對象的實際類型的方法表;
  2. 虛擬機搜索方法簽名;
  3. 調用方法。

動態綁定和靜態綁定的特色

靜態綁定

靜態綁定在編譯時期觸發,那麼它的主要特色是

一、編譯期觸發,可以提前知道代碼錯誤

二、提升程序運行效率

動態綁定

一、使用動態綁定的前提條件可以提升代碼的可用性,使代碼更加靈活。

二、多態是設計模式的基礎,可以下降耦合性。

參考: https://blog.csdn.net/zhangjk1993/article/details/24066085

相關文章
相關標籤/搜索