日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
讓你懷疑人生的重載和重寫的區(qū)別

如果你認(rèn)為你對(duì)java的重載和重寫已經(jīng)很了解了,那么我想通過(guò)下面的例子你可能會(huì)感到懷疑人生了。如果你能完全回答對(duì)下面的題目,那我覺得你真的非常非常牛X了。

成都創(chuàng)新互聯(lián)長(zhǎng)期為上千余家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為吳川企業(yè)提供專業(yè)的成都網(wǎng)站建設(shè)、做網(wǎng)站,吳川網(wǎng)站改版等技術(shù)服務(wù)。擁有10余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

單一調(diào)度

 
 
 
  1. class Parent { 
  2.   void print(String a) { log.info("Parent - String"); } 
  3.   void print(Object a) { log.info("Parent - Object"); } 
  4.   
  5. class Child extends Parent { 
  6.   void print(String a) { log.info("Child - String"); } 
  7.   void print(Object a) { log.info("Child - Object"); } 

下面將會(huì)打印什么?

 
 
 
  1. String string = ""; 
  2. Object stringstringObject = string; 
  3.   
  4. // 打印什么? 
  5. Child child = new Child(); 
  6. child.print(string); 
  7. child.print(stringObject); 
  8.   
  9. Parent parent = new Child(); 
  10. parent.print(string); 
  11. parent.print(stringObject); 

答案:

 
 
 
  1. child.print(string);        // 打印: "Child - String" 
  2. child.print(stringObject);  // 打印: "Child - Object" 
  3.   
  4. parent.print(string);       // 打印: "Child - String" 
  5. parent.print(stringObject); // 打印: "Child - Object" 

print(string)和 parent.print(string)是 Java 面向?qū)ο蟪绦蛟O(shè)計(jì)的教科書示例。被調(diào)用的方法取決于實(shí)際的實(shí)例類型,而不是聲明的實(shí)例類型。例如,無(wú)論你將變量定義為 Child 還是 Parent,因?yàn)閷?shí)際的實(shí)例類型是 Child,都將調(diào)用 Child: : print。

第二組則更為復(fù)雜,因?yàn)槎际峭耆嗤淖址?。唯一的區(qū)別是字符串被聲明為 String,而 stringObject 被聲明為 Object。在處理方法參數(shù)時(shí),重要的是參數(shù)的聲明類型,而不是它的實(shí)際類型。即使實(shí)際參數(shù)類型是 String,也會(huì)調(diào)用 print (Object)

隱式重寫

 
 
 
  1. class Parent { 
  2.   void print(Object a) { log.info("Parent - Object"); } 
  3.   
  4. class Child extends Parent { 
  5.   void print(String a) { log.info("Child - String"); } 

打印什么?

 
 
 
  1. String string = ""; 
  2. Parent parent = new Child(); 
  3. parent.print(string); 

答案:

 
 
 
  1. parent.print(string);  // 打印: "Parent - Object" 

實(shí)際的實(shí)例類型是 Child,聲明的參數(shù)類型是 String,我們確實(shí)有一個(gè)為 Child: : print (String)定義的方法。實(shí)際上,這正是在前一個(gè)示例中調(diào)用 parent.print (string)時(shí)選擇的內(nèi)容。但是,這并不是在這里調(diào)用的方法。

在檢查子類重寫之前,Java 似乎首先選擇要調(diào)用哪個(gè)方法。在這種情況下,聲明的實(shí)例類型是 Parent,Parent 中唯一匹配的方法是 Parent: : print (Object)。然后,當(dāng) Java 檢查 Parent: : print (Object)的任何潛在重寫時(shí),它沒有找到任何重寫,因此這就是執(zhí)行的方法。

顯式重寫

 
 
 
  1. class Parent { 
  2.   void print(Object a) { log.info("Parent - Object!"); } 
  3.   void print(String a) { throw new RuntimeException(); } 
  4.   
  5. class Child extends Parent { 
  6.   void print(String a) { log.info("Child - String!"); } 

打印什么?

 
 
 
  1. String string = ""; 
  2. Parent parent = new Child(); 
  3. parent.print(string); 

答案:

 
 
 
  1. parent.print(string);  // 打印: "Child - String!" 

這個(gè)示例與前面的示例之間的唯一區(qū)別是,我們添加了一個(gè)新的 Parent: : print (String)方法。這個(gè)方法實(shí)際上從來(lái)沒有被執(zhí)行過(guò)——如果它運(yùn)行了,它會(huì)拋出一個(gè)異常!然而,它的存在使 Java 執(zhí)行了一個(gè)不同的方法。

在計(jì)算 Parent.print (String)時(shí),運(yùn)行時(shí)現(xiàn)在找到一個(gè)匹配的 Parent: : print (String)方法,然后看到這個(gè)方法被 Child: : print (String)重寫。

模糊參數(shù)

 
 
 
  1. class Foo { 
  2.   void print(Cloneable a) { log.info("I am cloneable!"); } 
  3.   void print(Map a) { log.info("I am Map!"); } 

下面打印的是什么?

 
 
 
  1. HashMap cloneableMap = new HashMap(); 
  2. Cloneable cloneable = cloneableMap; 
  3. Map map = cloneableMap; 
  4.   
  5. // What gets printed? 
  6. Foo foo = new Foo(); 
  7. foo.print(map); 
  8. foo.print(cloneable); 
  9. foo.print(cloneableMap); 

答案:

 
 
 
  1. foo.print(map);           // 打印: "I am Map!" 
  2. foo.print(cloneable);     // 打印: "I am cloneable!" 
  3. foo.print(cloneableMap);  // 編譯不通過(guò) 

與單一調(diào)度示例類似,這里重要的是參數(shù)的聲明類型,而不是實(shí)際類型。另外,如果有多個(gè)方法對(duì)于給定的參數(shù)同樣有效,Java會(huì)拋出一個(gè)編譯錯(cuò)誤,并強(qiáng)制你指定應(yīng)該調(diào)用哪個(gè)方法。

多重繼承-接口

 
 
 
  1. interface Father { 
  2.   default void print() { log.info("I am Father!"); } 
  3.   
  4. interface Mother { 
  5.   default void print() { log.info("I am Mother!"); } 
  6.   
  7. class Child implements Father, Mother {} 

下面打印的是什么?

 
 
 
  1. new Child().print(); 

與前面的示例類似,這個(gè)示例也編譯不通過(guò)。具體地說(shuō),Child 的類定義本身將無(wú)法編譯,因?yàn)樵?Father 和 Mother 中存在沖突的缺省方法。你需要修改 Child 類指定 Child: : print 的行為。

多重繼承-類和接口

 
 
 
  1. class ParentClass { 
  2.   void print() { log.info("I am a class!"); } 
  3.   
  4. interface ParentInterface { 
  5.   default void print() { log.info("I am an interface!"); } 
  6.   
  7. class Child extends ParentClass implements ParentInterface {} 

打印什么?

 
 
 
  1. new Child().print(); 

答案:

 
 
 
  1. new Child().print();  // 打印: "I am a class!" 

如果類和接口之間存在繼承沖突,那么類方法優(yōu)先。

傳遞性重寫

 
 
 
  1. class Parent { 
  2.   void print() { foo(); } 
  3.   void foo() { log.info("I am Parent!"); } 
  4.   
  5. class Child extends Parent { 
  6.   void foo() { log.info("I am Child!"); } 

打印什么?

 
 
 
  1. new Child().print(); 

答案:

 
 
 
  1. new Child().print();  // 打印: "I am Child!" 

重寫方法甚至對(duì)傳遞調(diào)用也會(huì)生效,閱讀 Parent 類的人可能認(rèn)為 Parent: : print 總是會(huì)調(diào)用 Parent: : foo。但是如果該方法被重寫,那么 Parent: : print 將調(diào)用重寫后的 foo ()版本。

私有重寫

 
 
 
  1. class Parent { 
  2.   void print() { foo(); } 
  3.   private void foo() { log.info("I am Parent!"); } 
  4.   
  5. class Child extends Parent { 
  6.   void foo() { log.info("I am Child!"); } 

打印什么?

 
 
 
  1. new Child().print(); 

答案:

 
 
 
  1. new Child().print();  // 打印: "I am Parent!" 

除了一點(diǎn)不同之外,這個(gè)與前一個(gè)例子完全相同?,F(xiàn)在將 Parent.foo()聲明為 private。因此,當(dāng) Parent.print()調(diào)用 foo()時(shí),不管子類中是否存在 foo()的其他實(shí)現(xiàn),也不管調(diào)用 print()的實(shí)例的實(shí)際類型如何。

靜態(tài)重寫

 
 
 
  1. class Parent { 
  2.   static void print() { log.info("I am Parent!"); } 
  3.   
  4. class Child extends Parent { 
  5.   static void print() { log.info("I am Child!"); } 

打印什么?

 
 
 
  1. Child child = new Child(); 
  2. Parent parent = child; 
  3.   
  4. parent.print(); 
  5. child.print(); 

答案:

 
 
 
  1. parent.print(); // 打印: "I am Parent!" 
  2. child.print();  // 打印: "I am Child!" 

Java 不允許重寫靜態(tài)方法。如果在父類和子類中定義了相同的靜態(tài)方法,那么實(shí)例的實(shí)際類型根本不重要。只有聲明的類型用于確定調(diào)用兩個(gè)方法中的哪一個(gè)。

這是使用@override注解標(biāo)記所有重寫方法的另一個(gè)原因。在上面的例子中,在向 Child: : print 添加注解時(shí),你會(huì)得到一個(gè)編譯錯(cuò)誤,告訴你由于方法是靜態(tài)的,因此無(wú)法重寫該方法。

靜態(tài)鏈接

 
 
 
  1. class Parent { 
  2.   void print() { staticMethod(); instanceMethod(); } 
  3.   static void staticMethod() { log.info("Parent::staticMethod"); } 
  4.   void instanceMethod() { log.info("Parent::instanceMethod"); } 
  5.   
  6. class Child extends Parent { 
  7.   static void staticMethod() { log.info("Child::staticMethod"); } 
  8.   void instanceMethod() { log.info("Child::instanceMethod"); } 

打印什么?

 
 
 
  1. Child child = new Child(); 
  2. child.print(); 

答案:

 
 
 
  1. Parent::staticMethod 
  2. Child::instanceMethod 

這是我們之前討論過(guò)的一些不同概念的組合。例如,即使調(diào)用方位于父方法中,重寫也會(huì)生效。但是,對(duì)于靜態(tài)方法,即使變量的聲明類型是 Child,也要調(diào)用 Parent: : staticMethod,因?yàn)橛兄虚g print ()方法。

總結(jié)

如果說(shuō)有什么值得注意的地方,那就是繼承非常非常棘手,而且很容易出錯(cuò)。


標(biāo)題名稱:讓你懷疑人生的重載和重寫的區(qū)別
當(dāng)前鏈接:http://www.5511xx.com/article/djscieg.html