這篇文章主要介紹“重載和重寫的區(qū)別有哪些”,在日常操作中,相信很多人在重載和重寫的區(qū)別有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”重載和重寫的區(qū)別有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
武寧網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站開發(fā)等網(wǎng)站項目制作,到程序開發(fā),運營維護。創(chuàng)新互聯(lián)于2013年開始到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
單一調(diào)度
class Parent { void print(String a) { log.info("Parent - String"); } void print(Object a) { log.info("Parent - Object"); } } class Child extends Parent { void print(String a) { log.info("Child - String"); } void print(Object a) { log.info("Child - Object"); } }
下面將會打印什么?
String string = ""; Object stringstringObject = string; // 打印什么? Child child = new Child(); child.print(string); child.print(stringObject); Parent parent = new Child(); 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 面向?qū)ο蟪绦蛟O(shè)計的教科書示例。被調(diào)用的方法取決于實際的實例類型,而不是聲明的實例類型。例如,無論你將變量定義為 Child 還是 Parent,因為實際的實例類型是 Child,都將調(diào)用 Child: : print。
第二組則更為復(fù)雜,因為都是完全相同的字符串。唯一的區(qū)別是字符串被聲明為 String,而 stringObject 被聲明為 Object。在處理方法參數(shù)時,重要的是參數(shù)的聲明類型,而不是它的實際類型。即使實際參數(shù)類型是 String,也會調(diào)用 print (Object)
隱式重寫
class Parent { void print(Object a) { log.info("Parent - Object"); } } class Child extends Parent { void print(String a) { log.info("Child - String"); } }
打印什么?
String string = ""; Parent parent = new Child(); parent.print(string);
答案:
parent.print(string); // 打印: "Parent - Object"
實際的實例類型是 Child,聲明的參數(shù)類型是 String,我們確實有一個為 Child: : print (String)定義的方法。實際上,這正是在前一個示例中調(diào)用 parent.print (string)時選擇的內(nèi)容。但是,這并不是在這里調(diào)用的方法。
在檢查子類重寫之前,Java 似乎首先選擇要調(diào)用哪個方法。在這種情況下,聲明的實例類型是 Parent,Parent 中唯一匹配的方法是 Parent: : print (Object)。然后,當(dāng) Java 檢查 Parent: : print (Object)的任何潛在重寫時,它沒有找到任何重寫,因此這就是執(zhí)行的方法。
顯式重寫
class Parent { void print(Object a) { log.info("Parent - Object!"); } void print(String a) { throw new RuntimeException(); } } class Child extends Parent { void print(String a) { log.info("Child - String!"); } }
打印什么?
String string = ""; Parent parent = new Child(); parent.print(string);
答案:
parent.print(string); // 打印: "Child - String!"
這個示例與前面的示例之間的唯一區(qū)別是,我們添加了一個新的 Parent: : print (String)方法。這個方法實際上從來沒有被執(zhí)行過——如果它運行了,它會拋出一個異常!然而,它的存在使 Java 執(zhí)行了一個不同的方法。
在計算 Parent.print (String)時,運行時現(xiàn)在找到一個匹配的 Parent: : print (String)方法,然后看到這個方法被 Child: : print (String)重寫。
模糊參數(shù)
class Foo { void print(Cloneable a) { log.info("I am cloneable!"); } void print(Map a) { log.info("I am Map!"); } }
下面打印的是什么?
HashMap cloneableMap = new HashMap(); Cloneable cloneable = cloneableMap; Map map = cloneableMap; // What gets printed? Foo foo = new Foo(); foo.print(map); foo.print(cloneable); foo.print(cloneableMap);
答案:
foo.print(map); // 打印: "I am Map!" foo.print(cloneable); // 打印: "I am cloneable!" foo.print(cloneableMap); // 編譯不通過
與單一調(diào)度示例類似,這里重要的是參數(shù)的聲明類型,而不是實際類型。另外,如果有多個方法對于給定的參數(shù)同樣有效,Java會拋出一個編譯錯誤,并強制你指定應(yīng)該調(diào)用哪個方法。
多重繼承-接口
interface Father { default void print() { log.info("I am Father!"); } } interface Mother { default void print() { log.info("I am Mother!"); } } class Child implements Father, Mother {}
下面打印的是什么?
new Child().print();
與前面的示例類似,這個示例也編譯不通過。具體地說,Child 的類定義本身將無法編譯,因為在 Father 和 Mother 中存在沖突的缺省方法。你需要修改 Child 類指定 Child: : print 的行為。
多重繼承-類和接口
class ParentClass { void print() { log.info("I am a class!"); } } interface ParentInterface { default void print() { log.info("I am an interface!"); } } class Child extends ParentClass implements ParentInterface {}
打印什么?
new Child().print();
答案:
new Child().print(); // 打印: "I am a class!"
如果類和接口之間存在繼承沖突,那么類方法優(yōu)先。
傳遞性重寫
class Parent { void print() { foo(); } void foo() { log.info("I am Parent!"); } } class Child extends Parent { void foo() { log.info("I am Child!"); } }
打印什么?
new Child().print();
答案:
new Child().print(); // 打印: "I am Child!"
重寫方法甚至對傳遞調(diào)用也會生效,閱讀 Parent 類的人可能認為 Parent: : print 總是會調(diào)用 Parent: : foo。但是如果該方法被重寫,那么 Parent: : print 將調(diào)用重寫后的 foo ()版本。
私有重寫
class Parent { void print() { foo(); } private void foo() { log.info("I am Parent!"); } } class Child extends Parent { void foo() { log.info("I am Child!"); } }
打印什么?
new Child().print();
答案:
new Child().print(); // 打印: "I am Parent!"
除了一點不同之外,這個與前一個例子完全相同。現(xiàn)在將 Parent.foo()聲明為 private。因此,當(dāng) Parent.print()調(diào)用 foo()時,不管子類中是否存在 foo()的其他實現(xiàn),也不管調(diào)用 print()的實例的實際類型如何。
靜態(tài)重寫
class Parent { static void print() { log.info("I am Parent!"); } } class Child extends Parent { static void print() { log.info("I am Child!"); } }
打印什么?
Child child = new Child(); Parent parent = child; parent.print(); child.print();
答案:
parent.print(); // 打印: "I am Parent!" child.print(); // 打印: "I am Child!"
Java 不允許重寫靜態(tài)方法。如果在父類和子類中定義了相同的靜態(tài)方法,那么實例的實際類型根本不重要。只有聲明的類型用于確定調(diào)用兩個方法中的哪一個。
這是使用@override注解標記所有重寫方法的另一個原因。在上面的例子中,在向 Child: : print 添加注解時,你會得到一個編譯錯誤,告訴你由于方法是靜態(tài)的,因此無法重寫該方法。
靜態(tài)鏈接
class Parent { void print() { staticMethod(); instanceMethod(); } static void staticMethod() { log.info("Parent::staticMethod"); } void instanceMethod() { log.info("Parent::instanceMethod"); } } class Child extends Parent { static void staticMethod() { log.info("Child::staticMethod"); } void instanceMethod() { log.info("Child::instanceMethod"); } }
打印什么?
Child child = new Child(); child.print();
答案:
Parent::staticMethod Child::instanceMethod
這是我們之前討論過的一些不同概念的組合。例如,即使調(diào)用方位于父方法中,重寫也會生效。但是,對于靜態(tài)方法,即使變量的聲明類型是 Child,也要調(diào)用 Parent: : staticMethod,因為有中間 print ()方法。
到此,關(guān)于“重載和重寫的區(qū)別有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
新聞名稱:重載和重寫的區(qū)別有哪些
本文URL:http://weahome.cn/article/iijsij.html