java動態(tài)綁定和靜態(tài)綁定用法實例詳解
本文實例講述了java動態(tài)綁定和靜態(tài)綁定用法。分享給大家供大家參考,具體如下:
背景
1.當子類和父類存在同一個方法,子類重寫了父類的方法,程序在運行時調(diào)用的是父類的方法還是子類的重寫方法呢(尤其是存在向上類型轉(zhuǎn)換的情況)?
2.當一個類中存在方法名相同但參數(shù)不同(重載)的方法,程序在執(zhí)行的時候該如何辨別區(qū)分使用哪個方法呢?
在java中存在綁定的機制解決以上疑問。
綁定
綁定:將一個方法的調(diào)用與方法所在的類(方法主體)關聯(lián)起來。即決定調(diào)用哪個方法和變量。
在java中,綁定分為靜態(tài)綁定和動態(tài)綁定。也叫作前期綁定和后期綁定。
靜態(tài)綁定
在程序執(zhí)行以前已經(jīng)被綁定(即在編譯過程中就已經(jīng)知道這個方法到底是哪個類中的方法)。
java當中的方法只有final、static、private修飾的的方法和構(gòu)造方法是靜態(tài)綁定的。
private修飾的方法:private修飾的方法是不能被繼承的,因此子類無法訪問父類中private修飾的方法。所以只能通過父類對象來調(diào)用該方法體。因此可以說private方法和定義這個方法的類綁定在了一起。
final修飾的方法:可以被子類繼承,但是不能被子類重寫(覆蓋),所以在子類中調(diào)用的實際是父類中定義的final方法。(使用final修飾方法的兩個好處:(1)防止方法被覆蓋;(2)關閉java中的動態(tài)綁定)。
static修飾的方法:可以被子類繼承,但是不能被子類重寫(覆蓋),但是可以被子類隱藏。(這里意思是數(shù)哦如果父類里有一個static方法,它的子類里如果沒有對應的方法,那么當子類對象調(diào)用這個方法時就會使用父類中的方法,而如果子類中定義了相同的方法,則會調(diào)用子類中定義的方法,唯一的不同就是:當子類對象向上類型轉(zhuǎn)換為父類對象時,不論子類中有沒有定義這個靜態(tài)方法,該對象都會使用父類中的靜態(tài)方法,因此這里說靜態(tài)方法可以被隱藏而不能被覆蓋。這與子類隱藏父類中的成員變量是一樣的。隱藏和覆蓋的區(qū)別在于,子類對象轉(zhuǎn)換成父類對象后,能夠訪問父類被隱藏的變量和方法,而不能訪問父類被覆蓋的方法)。
構(gòu)造方法:構(gòu)造方法也是不能被繼承的(因為子類是通過super方法調(diào)用父類的構(gòu)造函數(shù),或者是jvm自動調(diào)用父類的默認構(gòu)造方法),因此編譯時也可以知道這個構(gòu)造方法方法到底是屬于哪個類的。
因此,一個方法被繼承,或者是被繼承后不能被覆蓋,那么這個方法就采用靜態(tài)綁定
動態(tài)綁定
在運行時期根據(jù)具體對象的類型進行綁定。
若一種語言實現(xiàn)了后期綁定,同時必須提供一些機制,可在運行期間判斷對象的類型,并分別調(diào)用適當?shù)姆椒āR簿褪钦f,編譯器此時依然不知道對象的類型,但方法調(diào)用機制能自己去調(diào)查,找到正確的方法主體。不同的語言對后期綁定的實現(xiàn)方法是有所區(qū)別的,但我們至少可以這樣認為:它們都要在對象中安插某些特殊類型的信息。
動態(tài)綁定的過程:
1.虛擬機提取對象實際類型的方法表
2.虛擬機搜索方法簽名
3.調(diào)用方法
java中重載的方法使用靜態(tài)綁定,重寫的方法使用動態(tài)綁定。
實驗
package practice; public class Bind{ public static void main(String[] args) { Child c = new Child(); Parent p = c; System.out.println(p.getPristr()); System.out.println(c.pristr); c.print(); p.print(); c.print1(); p.print1(); c.print2(); p.print2(); } } class Parent{ private String pristr = "parent private string"; String pubstr = "public string"; public String getPristr() { return pristr; } public void setPristr(String pristr) { this.pristr = pristr; } public Parent() { System.out.println("parent構(gòu)造函數(shù)"); } final public void print() { System.out.println("parent的print"); } public static void print1() { System.out.println("parent的print1"); } public void print2() { System.out.println("parent的print2"); } } class Child extends Parent{ String pristr = "child private string"; String pubstr = "public string"; public Child() { System.out.println("child構(gòu)造函數(shù)"); } public static void print1() { System.out.println("child的print1"); } public void print2() { System.out.println("child的print2"); } }
結(jié)果
parent構(gòu)造函數(shù)
child構(gòu)造函數(shù)
parent private string
child private string
parent的print
parent的print
child的print1
parent的print1
child的print2
child的print2
更多java相關內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O計入門與進階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設計有所幫助。
相關文章
springboot?vue接口測試前后端樹節(jié)點編輯刪除功能
這篇文章主要為大家介紹了springboot?vue接口測試前后端樹節(jié)點編輯刪除功能,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05Java中的List接口實現(xiàn)類LinkList和ArrayList詳解
這篇文章主要介紹了Java中的List接口實現(xiàn)類LinkList和ArrayList詳解,List接口繼承自Collection接口,是單列集合的一個重要分支,實現(xiàn)了List接口的對象稱為List集合,在List集合中允許出現(xiàn)重復的元素,所有的元素是以一種線性方式進行存儲的,需要的朋友可以參考下2024-01-01前端如何調(diào)用后端接口進行數(shù)據(jù)交互詳解(axios和SpringBoot)
一般來講前端不會給后端接口,而是后端給前端接口的情況比較普遍,下面這篇文章主要給大家介紹了關于前端如何調(diào)用后端接口進行數(shù)據(jù)交互的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-03-03SpringBoot快速集成jxls-poi(自定義模板,支持本地文件導出,在線文件導出)
這篇文章主要介紹了SpringBoot快速集成jxls-poi(自定義模板,支持本地文件導出,在線文件導出),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09Springboot如何實現(xiàn)對配置文件中的明文密碼加密
這篇文章主要介紹了Springboot如何實現(xiàn)對配置文件中的明文密碼加密問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12BeanUtils.copyProperties使用總結(jié)以及注意事項說明
這篇文章主要介紹了BeanUtils.copyProperties使用總結(jié)以及注意事項說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08