成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

讓你懷疑人生的重載和重寫的區別

開發 前端
如果你認為你對java的重載和重寫已經很了解了,那么我想通過下面的例子你可能會感到懷疑人生了。如果你能完全回答對下面的題目,那我覺得你真的非常非常牛X了。

如果你認為你對java的重載和重寫已經很了解了,那么我想通過下面的例子你可能會感到懷疑人生了。如果你能完全回答對下面的題目,那我覺得你真的非常非常牛X了。

[[349661]]

單一調度

  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"); } 

下面將會打印什么?

  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 面向對象程序設計的教科書示例。被調用的方法取決于實際的實例類型,而不是聲明的實例類型。例如,無論你將變量定義為 Child 還是 Parent,因為實際的實例類型是 Child,都將調用 Child: : print。

第二組則更為復雜,因為都是完全相同的字符串。唯一的區別是字符串被聲明為 String,而 stringObject 被聲明為 Object。在處理方法參數時,重要的是參數的聲明類型,而不是它的實際類型。即使實際參數類型是 String,也會調用 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" 

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

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

顯式重寫

  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!" 

這個示例與前面的示例之間的唯一區別是,我們添加了一個新的 Parent: : print (String)方法。這個方法實際上從來沒有被執行過——如果它運行了,它會拋出一個異常!然而,它的存在使 Java 執行了一個不同的方法。

在計算 Parent.print (String)時,運行時現在找到一個匹配的 Parent: : print (String)方法,然后看到這個方法被 Child: : print (String)重寫。

模糊參數

  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);  // 編譯不通過 

與單一調度示例類似,這里重要的是參數的聲明類型,而不是實際類型。另外,如果有多個方法對于給定的參數同樣有效,Java會拋出一個編譯錯誤,并強制你指定應該調用哪個方法。

多重繼承-接口

  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(); 

與前面的示例類似,這個示例也編譯不通過。具體地說,Child 的類定義本身將無法編譯,因為在 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!" 

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

傳遞性重寫

  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!" 

重寫方法甚至對傳遞調用也會生效,閱讀 Parent 類的人可能認為 Parent: : print 總是會調用 Parent: : foo。但是如果該方法被重寫,那么 Parent: : print 將調用重寫后的 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!" 

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

靜態重寫

  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 不允許重寫靜態方法。如果在父類和子類中定義了相同的靜態方法,那么實例的實際類型根本不重要。只有聲明的類型用于確定調用兩個方法中的哪一個。

這是使用@override注解標記所有重寫方法的另一個原因。在上面的例子中,在向 Child: : print 添加注解時,你會得到一個編譯錯誤,告訴你由于方法是靜態的,因此無法重寫該方法。

靜態鏈接

  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 

這是我們之前討論過的一些不同概念的組合。例如,即使調用方位于父方法中,重寫也會生效。但是,對于靜態方法,即使變量的聲明類型是 Child,也要調用 Parent: : staticMethod,因為有中間 print ()方法。

總結

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

 

責任編輯:趙寧寧 來源: 科技繆繆
相關推薦

2021-06-10 18:59:41

Java編程語言

2017-09-06 15:40:36

大數據動向

2025-06-17 10:00:00

函數重載函數重寫C++

2023-09-22 22:49:15

C++重載重寫

2009-08-25 17:15:50

C#隱藏C#重寫C#重載

2022-01-11 06:53:23

面試重寫重載

2020-06-17 12:22:44

C覆蓋重載

2024-04-28 12:55:46

redis頻道機制

2017-10-31 10:12:12

無人駕駛安全性乘客信任

2023-05-29 08:32:40

JAVA重寫重載

2017-09-28 09:46:56

5G通信互聯

2016-03-28 09:39:54

2019-07-24 10:11:51

jdkjreJava

2016-11-02 16:13:19

代碼開發技能

2023-12-05 15:24:46

2020-08-13 07:56:48

JDK枚舉類安全

2012-09-06 09:36:17

谷歌NatiShalom數據處理

2021-10-12 15:58:53

手機數據隱私

2020-09-14 15:57:53

Vue和React

2023-11-27 00:48:46

displayvisibility
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩欧美不卡 | 国产91视频免费 | 国产男女视频网站 | 欧美日本一区二区 | 日本午夜一区二区三区 | 亚洲视频中文 | 久久黄网 | 国产欧美日韩一区 | 国产精品不卡 | 伊人在线 | 色综合久久久 | 九九在线视频 | 国产黄色大片网站 | 亚洲欧美视频 | 动漫www.被爆羞羞av44 | 日本一区视频在线观看 | 欧美亚洲在线 | 欧美高清视频一区 | 亚洲免费视频在线观看 | 色小姐综合网 | 91社区在线高清 | 成人国产精品一级毛片视频毛片 | 韩日有码 | 日韩精品视频在线观看一区二区三区 | av先锋资源| 911精品国产 | 一级毛片视频 | 黄色片在线免费看 | 成年人黄色一级片 | 国产精品久久久久久久7电影 | 欧美一区免费 | 爱草在线 | 免费久久视频 | 亚洲精品在线视频 | 国产在线一区二区 | 99精品欧美一区二区三区 | 成年人免费看 | 麻豆av网站| 在线成人av | 一区二区在线免费观看 | 日本免费黄色一级片 |