重寫和隱藏方法 實例方法
子類中的實例方法的簽名(名稱,加上其參數的數量和類型)和返回類型與超類中的實例方法相同,將覆蓋超類的方法。
子類覆蓋方法的能力允許類從行為“足夠接近”的超類繼承,然后根據需要修改行為,重寫方法與它重寫的方法具有相同的名稱、數量和參數類型,以及返回類型。重寫方法還可以返回由被重寫方法返回的類型的子類型,此子類型稱為協變返回類型。
覆蓋方法時,你可能希望使用@Override注解來指示編譯器你要覆蓋超類中的方法,如果由于某種原因,編譯器檢測到該方法在其中一個超類中不存在,那么它將生成錯誤,有關@Override的更多信息,請參閱注解。
靜態方法如果子類定義的靜態方法與超類中的靜態方法具有相同的簽名,則子類中的方法會隱藏超類中的方法。
隱藏靜態方法和覆蓋實例方法之間的區別具有重要意義:
被調用的重寫的實例方法的版本是子類中的版本。
被調用的隱藏靜態方法的版本取決于它是從超類還是從子類調用的。
考慮一個包含兩個類的示例,第一個是Animal,它包含一個實例方法和一個靜態方法:
public class Animal { public static void testClassMethod() { System.out.println("The static method in Animal"); } public void testInstanceMethod() { System.out.println("The instance method in Animal"); } }
第二個類是Animal的一個子類,叫做Cat:
public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } }
Cat類重寫Animal中的實例方法,并隱藏Animal中的靜態方法,此類中的main方法創建Cat的實例,并在類上調用testClassMethod()并在實例上調用testInstanceMethod()。
該程序的輸出如下:
The static method in Animal The instance method in Cat
正如所承諾的那樣,被調用的隱藏靜態方法的版本是超類中的版本,被調用的重寫實例方法的版本是子類中的版本。
接口方法接口中的默認方法和抽象方法與實例方法一樣是繼承的,但是,當類或接口的超類型提供具有相同簽名的多個默認方法時,Java編譯器遵循繼承規則來解決名稱沖突,這些規則由以下兩個原則驅動:
實例方法優先于接口默認方法。
考慮以下類和接口:
public class Horse { public String identifyMyself() { return "I am a horse."; } } public interface Flyer { default public String identifyMyself() { return "I am able to fly."; } } public interface Mythical { default public String identifyMyself() { return "I am a mythical creature."; } } public class Pegasus extends Horse implements Flyer, Mythical { public static void main(String... args) { Pegasus myApp = new Pegasus(); System.out.println(myApp.identifyMyself()); } }
方法Pegasus.identifyMyself返回字符串I am a horse。
已經被其他候選者覆蓋的方法將被忽略,當超類型共享一個共同的祖先時,就會出現這種情況。
考慮以下接口和類:
public interface Animal { default public String identifyMyself() { return "I am an animal."; } } public interface EggLayer extends Animal { default public String identifyMyself() { return "I am able to lay eggs."; } } public interface FireBreather extends Animal { } public class Dragon implements EggLayer, FireBreather { public static void main (String... args) { Dragon myApp = new Dragon(); System.out.println(myApp.identifyMyself()); } }
方法Dragon.identifyMyself返回字符串I am able to lay eggs。
如果兩個或多個獨立定義的默認方法沖突,或者默認方法與抽象方法沖突,則Java編譯器會產生編譯器錯誤,你必須顯式覆蓋超類型方法。
考慮一下現在可以飛行的計算機控制汽車的例子,你有兩個接口(OperateCar和FlyCar)為同一方法提供默認實現(startEngine):
public interface OperateCar { // ... default public int startEngine(EncryptedKey key) { // Implementation } } public interface FlyCar { // ... default public int startEngine(EncryptedKey key) { // Implementation } }
實現OperateCar和FlyCar的類必須覆蓋方法startEngine,你可以使用super關鍵字調用任何默認實現。
public class FlyingCar implements OperateCar, FlyCar { // ... public int startEngine(EncryptedKey key) { FlyCar.super.startEngine(key); OperateCar.super.startEngine(key); } }
super之前的名稱(在此示例中為FlyCar或OperateCar)必須引用定義或繼承默認調用方法的直接超接口,這種形式的方法調用不限于區分包含具有相同簽名的默認方法的多個已實現接口,你可以使用super關鍵字在類和接口中調用默認方法。
類中的繼承實例方法可以覆蓋抽象接口方法,考慮以下接口和類:
public interface Mammal { String identifyMyself(); } public class Horse { public String identifyMyself() { return "I am a horse."; } } public class Mustang extends Horse implements Mammal { public static void main(String... args) { Mustang myApp = new Mustang(); System.out.println(myApp.identifyMyself()); } }
方法Mustang.identifyMyself返回字符串I am a horse,Mustang類繼承了Horse類中的方法identifyMyself,它覆蓋了Mammal接口中同名的抽象方法。
注意:接口中的靜態方法永遠不會被繼承。修飾符
重寫方法的修飾符可以允許比被重寫方法更多但不是更少的訪問,例如,超類中的protected實例方法可以在子類中是public,但不能是private。
如果嘗試將超類中的實例方法更改為子類中的靜態方法,則會出現編譯時錯誤,反之亦然。
總結下表總結了在定義具有與超類中的方法相同的簽名的方法時發生的情況。
超類實例方法 | 超類靜態方法 | |
---|---|---|
子類實例方法 | 覆蓋 | 生成編譯時錯誤 |
子類靜態方法 | 生成編譯時錯誤 | 隱藏 |
注意:在子類中,你可以重載從超類繼承的方法,這樣的重載方法既不隱藏也不覆蓋超類實例方法 — 它們是新方法,對于子類是唯一的。上一篇:繼承 下一篇:多態性
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/72877.html
繼承 在前面的課程中,你已經多次看到了繼承,在Java語言中,類可以從其他類派生,從而從這些類繼承字段和方法。 定義:從另一個類派生的類稱為子類(也是派生類,擴展類或子類),派生子類的類稱為超類(也是基類或父類)。 除了Object沒有超類,每個類都有一個且只有一個直接超類(單繼承),在沒有任何其他顯式超類的情況下,每個類都隱式地是Object的子類。 類可以從派生自類的類派生的類派生,依此類推,...
使用super關鍵字 訪問超類成員 如果你的方法覆蓋了它的一個超類的方法,你可以通過使用關鍵字super來調用被重寫的方法,你也可以使用super來引用隱藏字段(盡管不鼓勵隱藏字段),慮這個類,Superclass: public class Superclass { public void printMethod() { System.out.println(Print...
多態性 多態性的字典定義是指生物學中的原理,其中生物體或物種可以具有許多不同的形式或階段,這個原則也可以應用于面向對象的編程和像Java語言之類的語言,類的子類可以定義它們自己的唯一行為,但仍然共享父類的一些相同功能。 可以通過對Bicycle類的微小修改來演示多態性,例如,可以將printDescription方法添加到顯示當前存儲在實例中的所有數據的類中。 public void printD...
Java? 教程 Java教程是為JDK 8編寫的,本頁面中描述的示例和實踐沒有利用在后續版本中引入的改進。 Java教程是希望使用Java編程語言創建應用程序的程序員的實用指南,其中包括數百個完整的工作示例和數十個課程,相關課程組被組織成教程。 覆蓋基礎知識的路徑 這些教程以書籍的形式提供,如Java教程,第六版,前往Amazon.com購買。 入門 介紹Java技術和安裝Java開發軟件并使用...
摘要:抽象數據類型的多個不同表示可以共存于同一個程序中,作為實現接口的不同類。封裝和信息隱藏信息隱藏將精心設計的模塊與不好的模塊區分開來的唯一最重要的因素是其隱藏內部數據和其他模塊的其他實施細節的程度。 大綱 面向對象的標準基本概念:對象,類,屬性,方法和接口OOP的獨特功能 封裝和信息隱藏 繼承和重寫 多態性,子類型和重載 靜態與動態分派 Java中一些重要的Object方法設計好的類面向...
閱讀 3776·2021-08-30 09:47
閱讀 3703·2019-08-30 15:56
閱讀 680·2019-08-30 14:18
閱讀 702·2019-08-29 16:17
閱讀 2069·2019-08-29 11:07
閱讀 647·2019-08-26 13:53
閱讀 3449·2019-08-26 10:26
閱讀 2497·2019-08-23 18:30