1. 程式人生 > >java 方法調用綁定

java 方法調用綁定

通過 由於 ner exti 運行時 自己 擦除 ava 導出

將一個方法調用同一個方法主體關聯起來被稱為綁定

若在程序執行前期進行綁定(如果有的話,由編譯器和連接程序實現),叫做前期綁定

當編譯器只有一個引用時,它無法知道究竟調用哪個方法才對,解決的辦法就是後期綁定,它的含義就是在運行時根據對象的類型進行綁定。後期綁定也叫做動態綁定或運行時綁定

java中除了static方法和final(private方法屬於final方法)之外,其他所有的方法都是後期綁定。這意味著同城情況下,我們不必判定是否應該進行後期綁定----它會自動發生。

有一個基類Shape,以及多個導出類--Circle、Square、Triangle等,每個類中都有draw(),erase()方法,向上轉型可以像下條語句這麽簡單:

Shape s = new Circle();

這裏,創建了一個Circle對象,並把得到的引用立即賦值給Shape,這樣看似錯誤(將一種類型賦值給另一種類型);但實際上是沒有問題的,因為通過繼承,Circle就是一種Shape

假設你調用一個基類方法(它已在導出類中被覆蓋)

s.draw();

你可能認為調用的是Shapedraw(),因為這畢竟是一個Shape的引用,那麽編譯器是怎麽知道去做其他的事情呢?由於後期綁定(多態),還是調用了Circle.draw()方法。

下面的例子稍微有不同:

public class Shape
{
    public void draw(){}
    
public void erase(){} } public class Circle extends Shape { public void draw() { System.out.println("Circle.draw()"); } public void erase() { System.out.println("Circle.erase()"); } } public class Square extends Shape { public void draw() { System.out.println(
"Square.draw()"); } public void erase() { System.out.println("Square.erase()"); } } public class Triangle extends Shape { public void draw() { System.out.println("Triangle.draw()"); } public void erase() { System.out.println("Triangle.erase()"); } } public class RandomShapeGenerator { private Random rand = new Random(47); public Shape next() { switch(rand.nextInt(3)) { default: case 0 : return new Circle(); case 1 : return new Square(); case 2 : return new Triangle(); } } } public class Shapes { private static RandomShapeGenerator rsg = new RandomShapeGenerator(); public static void main(String[] args) { Shape [] s = new Shape[9]; for (int i = 0; i < s.length; i++) s [i] = rsg.next(); for (Shape shp : s) { shp.draw(); } } } 輸出為: Triangle.draw() Triangle.draw() Square.draw() Triangle.draw() Square.draw() Triangle.draw() Square.draw() Triangle.draw() Circle.draw()

Shape基類為自它那裏繼承來的所有導出類建立了一個公用接口----也就是說,所有形狀都是可描繪和擦除。導出類通過覆蓋這些定義,來為每種特殊類型的幾何形狀提供單獨的行為。

RandomShapeGenerator是一種“工廠”,在我們每次調用next()方法時,它可以隨機選擇的為Shape對象產生一個引用。請註意向上轉型是在return語句後發生的。每個return語句取得一個指向某個CircleSquare或者Triangle的引用,並將其以Shape類型從next()方法中發送出去。所以無論我們在什麽時候調用next()方法時,是絕對不可能知道具體類型到底是什麽的,因為我們總是只能獲得一個通用的Shape引用。

main()包含了一個Shape引用組成的數組,通過調用RandomShapeGenerator.next()來填入數據。此時,我們只知道自己擁有一些Shape,初次之外不會知道更具體的情況(編譯器也不知道)。然而,當我們遍歷數組時,並為每個數組元素調用draw()方法時,與類型有關的特定行為會神奇地正確發生。

隨機選擇幾何形狀是為了更好的看出編譯器不需要獲得任何特殊信息就能進行正確的調用。對draw()方法的所有調用都是通過動態綁定進行的。

java 方法調用綁定