單一調度
classParent{voidprint(Stringa){log.info("Parent-String");}voidprint(Objecta){log.info("Parent-Object");}}classChildextendsParent{voidprint(Stringa){log.info("Child-String");}voidprint(Objecta){log.info("Child-Object");}}
下面將會打印什么?
Stringstring="";ObjectstringstringObject=string;//打印什么?Childchild=newChild();child.print(string);child.print(stringObject);Parentparent=newChild();parent.print(string);parent.print(stringObject);
答案:
child.print(string);//打印:"Child-String"child.print(stringObject);//打印:"Child-Object"parent.print(string);//打印:"Child-String"parent.print(stringObject);//打印:"Child-Object"
print(string)和 parent.print(string)是 Java 面向對象程序設計的教科書示例。被調用的方法取決于實際的實例類型,而不是聲明的實例類型。例如,無論你將變量定義為 Child 還是 Parent,因為實際的實例類型是 Child,都將調用 Child: : print。
第二組則更為復雜,因為都是完全相同的字符串。唯一的區別是字符串被聲明為 String,而 stringObject 被聲明為 Object。在處理方法參數時,重要的是參數的聲明類型,而不是它的實際類型。即使實際參數類型是 String,也會調用 print (Object)
隱式重寫
classParent{voidprint(Objecta){log.info("Parent-Object");}}classChildextendsParent{voidprint(Stringa){log.info("Child-String");}}
打印什么?
Stringstring="";Parentparent=newChild();parent.print(string);
答案:
parent.print(string);//打印:"Parent-Object"
實際的實例類型是 Child,聲明的參數類型是 String,我們確實有一個為 Child: : print (String)定義的方法。實際上,這正是在前一個示例中調用 parent.print (string)時選擇的內容。但是,這并不是在這里調用的方法。
在檢查子類重寫之前,Java 似乎首先選擇要調用哪個方法。在這種情況下,聲明的實例類型是 Parent,Parent 中唯一匹配的方法是 Parent: : print (Object)。然后,當 Java 檢查 Parent: : print (Object)的任何潛在重寫時,它沒有找到任何重寫,因此這就是執行的方法。
顯式重寫
classParent{voidprint(Objecta){log.info("Parent-Object!");}voidprint(Stringa){thrownewRuntimeException();}}classChildextendsParent{voidprint(Stringa){log.info("Child-String!");}}
打印什么?
Stringstring="";Parentparent=newChild();parent.print(string);
答案:
parent.print(string);//打印:"Child-String!"
這個示例與前面的示例之間的唯一區別是,我們添加了一個新的 Parent: : print (String)方法。這個方法實際上從來沒有被執行過——如果它運行了,它會拋出一個異常!然而,它的存在使 Java 執行了一個不同的方法。
在計算 Parent.print (String)時,運行時現在找到一個匹配的 Parent: : print (String)方法,然后看到這個方法被 Child: : print (String)重寫。
模糊參數
classFoo{voidprint(Cloneablea){log.info("Iamcloneable!");}voidprint(Mapa){log.info("IamMap!");}}
下面打印的是什么?
HashMapcloneableMap=newHashMap();Cloneablecloneable=cloneableMap;Mapmap=cloneableMap;//Whatgetsprinted?Foofoo=newFoo();foo.print(map);foo.print(cloneable);foo.print(cloneableMap);
答案:
foo.print(map);//打印:"IamMap!"foo.print(cloneable);//打印:"Iamcloneable!"foo.print(cloneableMap);//編譯不通過
與單一調度示例類似,這里重要的是參數的聲明類型,而不是實際類型。另外,如果有多個方法對于給定的參數同樣有效,Java會拋出一個編譯錯誤,并強制你指定應該調用哪個方法。
多重繼承-接口
interfaceFather{defaultvoidprint(){log.info("IamFather!");}}interfaceMother{defaultvoidprint(){log.info("IamMother!");}}classChildimplementsFather,Mother{}
下面打印的是什么?
newChild().print();
與前面的示例類似,這個示例也編譯不通過。具體地說,Child 的類定義本身將無法編譯,因為在 Father 和 Mother 中存在沖突的缺省方法。你需要修改 Child 類指定 Child: : print 的行為。
多重繼承-類和接口
classParentClass{voidprint(){log.info("Iamaclass!");}}interfaceParentInterface{defaultvoidprint(){log.info("Iamaninterface!");}}classChildextendsParentClassimplementsParentInterface{}
打印什么?
newChild().print();
答案:
newChild().print();//打印:"Iamaclass!"
如果類和接口之間存在繼承沖突,那么類方法優先。
傳遞性重寫
classParent{voidprint(){foo();}voidfoo(){log.info("IamParent!");}}classChildextendsParent{voidfoo(){log.info("IamChild!");}}
打印什么?
newChild().print();
答案:
newChild().print();//打印:"IamChild!"
重寫方法甚至對傳遞調用也會生效,閱讀 Parent 類的人可能認為 Parent: : print 總是會調用 Parent: : foo。但是如果該方法被重寫,那么 Parent: : print 將調用重寫后的 foo ()版本。
私有重寫
classParent{voidprint(){foo();}privatevoidfoo(){log.info("IamParent!");}}classChildextendsParent{voidfoo(){log.info("IamChild!");}}
打印什么?
newChild().print();
答案:
newChild().print();//打印:"IamParent!"
除了一點不同之外,這個與前一個例子完全相同?,F在將 Parent.foo()聲明為 private。因此,當 Parent.print()調用 foo()時,不管子類中是否存在 foo()的其他實現,也不管調用 print()的實例的實際類型如何。
靜態重寫
classParent{staticvoidprint(){log.info("IamParent!");}}classChildextendsParent{staticvoidprint(){log.info("IamChild!");}}
打印什么?
Childchild=newChild();Parentparent=child;parent.print();child.print();
答案:
parent.print();//打印:"IamParent!"child.print();//打印:"IamChild!"
Java 不允許重寫靜態方法。如果在父類和子類中定義了相同的靜態方法,那么實例的實際類型根本不重要。只有聲明的類型用于確定調用兩個方法中的哪一個。
這是使用@override注解標記所有重寫方法的另一個原因。在上面的例子中,在向 Child: : print 添加注解時,你會得到一個編譯錯誤,告訴你由于方法是靜態的,因此無法重寫該方法。
靜態鏈接
classParent{voidprint(){staticMethod();instanceMethod();}staticvoidstaticMethod(){log.info("Parent::staticMethod");}voidinstanceMethod(){log.info("Parent::instanceMethod");}}classChildextendsParent{staticvoidstaticMethod(){log.info("Child::staticMethod");}voidinstanceMethod(){log.info("Child::instanceMethod");}}
打印什么?
Childchild=newChild();child.print();
答案:
Parent::staticMethodChild::instanceMethod
這是我們之前討論過的一些不同概念的組合。例如,即使調用方位于父方法中,重寫也會生效。但是,對于靜態方法,即使變量的聲明類型是 Child,也要調用 Parent: : staticMethod,因為有中間 print ()方法。
到此,關于“重載和重寫的區別有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注本站網站,小編會繼續努力為大家帶來更多實用的文章!
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
c語言中正確的字符常量是用一對單引號將一個字符括起表示合法的字符常量。例如‘a’。數值包括整型、浮點型。整型可用十進制,八進制,十六進制。八進制前面要加0,后面...
2022年天津專場考試原定于3月19日舉行,受疫情影響確定延期,但目前延期后的考試時間推遲。 符合報名條件的考生,須在規定時間登錄招考資訊網(www.zha...
:喜歡聽,樂意看。指很受歡迎?!巴卣官Y料”喜聞樂見:[ xǐ wén lè jiàn ]詳細解釋1. 【解釋】:喜歡聽,樂意看。指很受歡迎。2. 【示例】:這是...
海航集團,成立于1993年,從單一的地方航空運輸企業發展成為跨國企業集團。因流動性危機,海航集團走上重整道路。據最新消息,海航集團重整計劃表決通過。下面,我們一起來具體了解一下吧。據海航集團官方微信公眾號10月23日消息,10月23日下午3點,海南省高級人民法院組織聯合工作組、管理人、債權人代表、出資人代表、債務人代表及職工代表等各相關方,對海航集團及相關企業破產重整案的各重整計劃草案表決情況進行...
CHF即Confederation Helvetica Franc,指的是瑞士法郎這-貨幣。瑞士法郎的英文名是Swiss Franc, CHF中的"CH” 是瑞士這一國家的拉丁文縮寫字母, "F”是法郎的縮寫字母,組合起來即為CHF,是一 種加密型數字貨幣。瑞士法郎主要是瑞士還有列支敦士登這兩個國家使用,由瑞士中央銀行發行,分為硬幣和紙幣兩個幣種,其中共...
(資料圖片)在生活中,很多人都不知道如何刪除小哨兵還原卡是什么意思,其實他的意思是非常簡單的,下面就是小編搜索到的如何刪除小哨兵還原卡相關的一些知識,我們一起來學習下吧!初次安裝小哨兵還原卡: 1、 準備好相對應的小哨兵還原卡的驅動程序;2、 開機進入Windows界面,安裝小哨兵還原卡的驅動,安裝完畢后重啟。3、 關機。4、 打開電腦側板,將小哨兵還原卡插在電腦主板的PCI槽或網槽上。5、 開機...