動態綁定 vs 靜態綁定

動態綁定(又名後期綁定)

動態綁定是指編譯器在編譯階段不知道要調用哪個方法,直到運行時才能確定。讓我們用個例子來解釋。譬如我們有一個叫作’SuperClass’的父類,還有一個繼承它的子類’SubClass’。現在SuperClass引用也可以賦給SubClass類型的對象。如果SuperClass中有個someMethod()的方法,而子類也重寫了這個方法,那麼當調用SuperClass引用的這個方法的時候,編譯器不知道該調用父類還是子類的方法,因爲編譯器不知道對象到底是什麼類型,只有到運行時才知道這個引用指向什麼對象。

...
SuperClass superClass1 = new SuperClass();
SuperClass superClass2 = new SubClass();
...
 
superClass1.someMethod(); // SuperClass version is called
superClass2.someMethod(); // SubClass version is called
....


我們可以看到雖然對象引用superClass1和superClass2都是SuperClass類型的,但是在運行時它們分別指向SuperClass和SubClass類型的對象。

所以在編譯階段,編譯器不清楚調用引用的someMethod()到底是調用子類還是父類的該方法。

所以方法的動態綁定是基於實際的對象類型,而不是它們聲明的對象引用類型。

靜態綁定(又名前期綁定)

如果編譯器可以在編譯階段就完成綁定,就叫作靜態綁定或前期綁定。基本上實例方法都在運行時綁定,所有的靜態方法都在編譯時綁定,所以靜態方法是靜態綁定的。因爲靜態方法是屬於類的方法,可以通過類名來訪問(我們也應該使用類名來訪問靜態方法,而不是使用對象引用來訪問),所以要訪問它們就必須在編譯階段就使用編譯類型信息來進行綁定。這也就解釋了爲什麼靜態方法實際上不能被重寫


類似的,訪問成員變量也是靜態綁定的,因爲Java不支持(實際上是不鼓勵)成員變量的多態行爲。下面看個例子:

class SuperClass{
...
public String someVariable = "Some Variable in SuperClass";
...
}
 
class SubClass extends SuperClass{
...
public String someVariable = "Some Variable in SubClass";
...
}
...
...
 
SuperClass superClass1 = new SuperClass();
SuperClass superClass2 = new SubClass();
 
System.out.println(superClass1.someVariable);
System.out.println(superClass2.someVariable);
...
輸出:

Some Variable in SuperClass
Some Variable in SuperClass


我們可以發現成員變量由對象引用聲明的類型決定,是由編譯器在編譯階段就知道的信息,所以是靜態綁定。另外一個靜態綁定的例子是私有的方法,因爲它們不會被繼承,編譯器在編譯階段就完成私有方法的綁定了。


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