日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 多态之“绑定”

發布時間:2024/9/30 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 多态之“绑定” 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在剛開始學習 JavaSE 時,學習多態時對下面幾段程序輸出的結果感覺到迷惑

public class Sub extends Super{public int num = 1; public int getNum(){return num;}public static void main(String[] args) {Super sup = new Sub();System.out.println("sup.num = "+sup.num); //調用父類的屬性System.out.println("sup.getNum() = "+sup.getNum()); //調用子類的方法} }class Super{public int num = 0;public int getNum(){return num;} }

輸出:
sup.num = 0
sup.getNum() = 1


當將方法定義為靜態時輸出又會是什么樣的呢?

public class Sub extends Super{public static int num = 1;public static int getNum(){return num;}public static void main(String[] args) {Super sup = new Sub();System.out.println("sup.num = "+sup.num); //調用父類的屬性System.out.println("sup.getNum() = "+sup.getNum()); //調用父類的方法} }class Super{public static int num = 0;public static int getNum(){return num;} }

輸出:
sup.num = 0
sup.getNum() = 0


如果將方法定義成私有的又會是什么結果呢?

public class Sub extends Super{private void f(){System.out.println("Sub f run........... ");}}class Super{private void f(){System.out.println("Super f run........... ");}public static void main(String[] args) {Super sup = new Sub();sup.f(); //調用父類的方法} }

輸出:
Super f run………..


在當時剛開始學 Java 時,當時的疑惑主要有:

  • 為什么第一個程序在向上轉型的過程中調用的是父類的字段,以及子類的方法
  • 為什么第二個程序在向上轉型的過程中調用的是父類的字段,以及父類的方法

后來在網上搜了一下知道了“綁定”這個概念,但是也只是很淺顯的知道了有這個概念,最近在看《Java 編程思想》對“綁定”這個概念有了更深刻的認識,現在分享出來供大家參考:

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

  • 靜態綁定:若程序執行前綁定 (如果有的話,由編譯器和鏈接程序實現),叫做前期綁定。
  • 后期綁定:在運行時根據對象的類型進行綁定。后期綁定也叫做動態綁定或運行時綁定。

在 Java 中除了 static 方法和 final 方法 (private 方法屬于 final 方法) 之外,其他的方法都屬于后期綁定。為什么要將一個方聲明為 final 的呢?因為這樣做可以有效“關閉”動態綁定,或者說告訴編譯器不需要對其進行動態綁定。

Java 中所有的方法都是通過動態綁定實現多態。因此子類在向上轉型時調用的是子類的方法 (此方法時非靜態的),這就可以解釋為什么在第一段程序中調用 getNum() 方法輸出的是子類的方法。

只有普通的方法調用是多態的,因此如果你要訪問某個作用域或靜態方法,這個訪問將在編譯器進行解析。正如第一個程序中輸出的是父類的成員,以及第二個程序中將方法修飾成 static 時輸出的就是父類的成員和父類的方法了 (失去了多態的特性)。

靜態方法是與類,而并非與單個對象相關聯的。如果你并不想將方法定義成靜態的還想要得到 Super.num,必須顯示的指明 super.num,就像下面這樣:

public class Sub extends Super{public int num = 1;public int getNum(){return super.num;}public static void main(String[] args) {Super sup = new Sub();System.out.println("sup.getNum() = "+sup.getNum());} }class Super{public int num = 0;public int getNum(){return num;} }

輸出:
sup.getNum() = 0


對于第三段程序將方法定義成 private 的,我們期望是輸出的是子類的方法運行,但是結果卻出我們所料,這是動態綁定的缺陷所造成的結果,以及包括上面的域與靜態方法都是它的缺陷造成的 (也就是說這兩種缺陷是前期綁定)。

結論

只有非 private 方法才可以被覆蓋,但是還是要注意覆蓋 private 方法的現象,這時編譯器雖然不會報錯,但是它不會按照我們期望的那樣執行。確切的說,在導出類中,對于基類中的 private 方法最好不要采取一樣的名字。

在這里再強調一下這句話:在 Java 中除了 static 方法和 final 方法 (private 方法屬于 final 方法) 之外,其他的方法都屬于后期綁定。

其實在實踐過程中,這種混淆的問題通常不會發生,因為你通常會將所有的域都設成 private 的,因此不能直接訪問它們,其副作用是只能通過方法獲取它們。另外,你幾乎不可能將基類中的域和導出類的域賦予相同的名字。

參考資料
《Java 編程思想》Bruce Eckel 著 陳昊鵬 譯

總結

以上是生活随笔為你收集整理的Java 多态之“绑定”的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。