super 和 this 关键字的比较+调用构造器(this)+动态绑定
【0】README
0.1) 本文描述+源代碼均 轉(zhuǎn)自 core java volume 1, 旨在加深對(duì) super 和 this關(guān)鍵字 的用法比較;
0.2) 最后還補(bǔ)充了 多態(tài)和動(dòng)態(tài)綁定 的定義 以及對(duì)動(dòng)態(tài)綁定進(jìn)行了詳細(xì)分析,這兩個(gè)定義給的非常棒;
【1】super 和 this 的比較:
1.1) 有人認(rèn)為super 和 this 引用是類似的概念,實(shí)際上,這樣比較并不太恰當(dāng);因?yàn)閟uper不是一個(gè)對(duì)象引用, 不能將super 賦給另一個(gè)對(duì)象變量,它只是一個(gè)編譯器調(diào)用超類方法的特殊關(guān)鍵字;
1.2)我們?cè)倏磗uper在構(gòu)造器中的應(yīng)用:
- 這里的super含義是: super(n, s, year, month, day) 是“調(diào)用超類Employee中含有 n、s、year、month 和 day” 參數(shù)的構(gòu)造器的簡(jiǎn)寫形式;
- 這是由于: Manager類的構(gòu)造器不能訪問 Employee類 的私有域, 所以必須利用 Employee類的構(gòu)造器對(duì)這部分私有域 進(jìn)行初始化;
Attention)
- A1)而且 使用 super調(diào)用構(gòu)造器的語句必須是 子類構(gòu)造器的第一條語句;
- A2)如果子類的構(gòu)造器沒有顯式地 調(diào)用超類的構(gòu)造器,則將自動(dòng)地調(diào)用超類默認(rèn)構(gòu)造器;
Annotation)關(guān)鍵字this + super 有兩個(gè)用途:
- A1)this的用途:一是引用隱式參數(shù)+二是調(diào)用該類其它的構(gòu)造器;
- A2)super的用途:一是調(diào)用超類 的方法 + 而是調(diào)用超類都構(gòu)造器;
【2】調(diào)用構(gòu)造器
2.1)調(diào)用構(gòu)造器的注意事項(xiàng) : 調(diào)用構(gòu)造器的語句只能作為 另一個(gè)構(gòu)造器的第一條語句出現(xiàn), 構(gòu)造參數(shù)既可以傳遞給本類的其他構(gòu)造器, 也可以傳遞給超類的構(gòu)造器;
2.2)看個(gè)荔枝(利用this調(diào)用其他構(gòu)造器):
2.3)Complementary
- C1)多態(tài): 一個(gè)對(duì)象變量可以指示多種實(shí)際類型的現(xiàn)象 被稱為多態(tài);(如上述代碼中的 e 即可以指向 Manager類 也可以指向 Employee類)
- C2)動(dòng)態(tài)綁定:在運(yùn)行時(shí)能夠自動(dòng)地選擇調(diào)用哪個(gè)方法的現(xiàn)象稱為動(dòng)態(tài)綁定;
【3】 動(dòng)態(tài)綁定
3.1)定義: 在運(yùn)行時(shí)能夠自動(dòng)地選擇調(diào)用哪個(gè)方法的現(xiàn)象稱為 動(dòng)態(tài)綁定 ;
如:
- e.getSalary() 調(diào)用能夠確定應(yīng)該執(zhí)行哪個(gè) getSalary 方法, 請(qǐng)注意, 這里雖然將e 聲明為 Employee 類型,但實(shí)際上 e 既可以引用Employee 類型的對(duì)象,也可以引用Manager 類型的對(duì)象;
3.2)看一下對(duì)象方法的執(zhí)行過程,調(diào)用過程的詳細(xì)描述(Description):
- D1)編譯器查看對(duì)象的聲明類型和方法名:例如可能存在方法 f(int) 和 方法 f(String), 編譯器將會(huì)一一列舉所有C類中名為f的方法和其超類中訪問屬性為public 且名
為f的方法; - D2)編譯器將查看調(diào)用方法時(shí)提供的參數(shù)類型:
重載解析:如果在所有名為f 的方法中存在一個(gè)與提供的參數(shù)類型完全匹配, 就選擇這個(gè)方法,這個(gè)過程叫做重載解析; - D3)如果是private、static、final 方法或者構(gòu)造器, 那么編譯器將可以正確地知道應(yīng)該調(diào)用哪個(gè)方法;我們將這種調(diào)用方式叫做靜態(tài)綁定;與此對(duì)應(yīng)的是,調(diào)用的方法依賴于隱式參數(shù)的實(shí)際
類型,并且在運(yùn)行時(shí)實(shí)現(xiàn)動(dòng)態(tài)綁定; - D4)當(dāng)程序運(yùn)行, 并且采用動(dòng)態(tài)綁定調(diào)用方法時(shí), 虛擬機(jī)一定調(diào)用與x 所引用對(duì)象的實(shí)際類型最合適的那個(gè)類的方法;假設(shè)x 的實(shí)際類型為D, 它是C類的子類, 如果 D類定義了 方法f(string), 就直接調(diào)用它,否則將在D類的超類中尋找f(string), 以此類推;
3.3)方法表:每次調(diào)用方法都要進(jìn)行搜索, 時(shí)間開銷相當(dāng)大, 因此虛擬機(jī)預(yù)先為每個(gè)類創(chuàng)建了一個(gè)方法表(method table), 其中列出了所有方法的簽名和實(shí)際調(diào)用 的方法;
Annotation)
- A1)方法簽名:方法的名字和參數(shù)列表稱為方法的簽名; 如,f(int) 和 f(String) 是兩個(gè)具有相同名字、不同簽名的方法;如果在子類中定義了一個(gè)與超類簽名相同的方法,那么子類中的這個(gè)方法就覆蓋了超類中的這個(gè)相同簽名的方法;
- A2)返回類型不是方法簽名的一部分:因此,在覆蓋方法時(shí), 一定要保證返回類型的兼容性;允許子類將覆蓋方法的返回類型定義為原返回類型的子類型;
如父類有: public Employee getBuddy(){}, 子類可以覆蓋它, public Manager getBuddy(){} ;我們說,這兩個(gè) getBuddy 方法具有 可協(xié)變的返回類型 ;
3.4)在運(yùn)行的時(shí)候, 調(diào)用 e.getSalary() 的解析過程(Procedure):
- P1)首先,虛擬機(jī)提取e 的實(shí)際類型的方法表: 既可能是Employee、Manager的方法表,也可能是 Employee 類的其他子類的方法表;
- P2)接下來, 虛擬機(jī)搜索定義 getSalary 簽名的類, 此時(shí),虛擬機(jī)已經(jīng)知道應(yīng)該調(diào)用哪個(gè)方法;
- P3)最后,虛擬機(jī)調(diào)用方法;
3.5)動(dòng)態(tài)綁定有一個(gè)重要的特性:無需對(duì)現(xiàn)在的代碼進(jìn)行修改, 就可以對(duì)程序進(jìn)行擴(kuò)展。
Alert)在覆蓋一個(gè)方法的時(shí)候, 子類方法不能低于超類方法的可見性;特別是, 如果超類方法是public, 子類方法一定要聲明為public;
總結(jié)
以上是生活随笔為你收集整理的super 和 this 关键字的比较+调用构造器(this)+动态绑定的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 韩国烧酒怎么喝 有什么方法
- 下一篇: 树的预备知识