真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

精選Java中的多態(tài)和繼承

在優(yōu)銳課架構(gòu)學(xué)習(xí)中,了解了關(guān)于用多態(tài)方法調(diào)用將你的大腦包圍在Java方法調(diào)用周圍

成都創(chuàng)新互聯(lián)云計(jì)算的互聯(lián)網(wǎng)服務(wù)提供商,擁有超過(guò)13年的服務(wù)器租用、托管服務(wù)器、云服務(wù)器、網(wǎng)絡(luò)空間、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn),已先后獲得國(guó)家工業(yè)和信息化部頒發(fā)的互聯(lián)網(wǎng)數(shù)據(jù)中心業(yè)務(wù)許可證。專業(yè)提供云主機(jī)、網(wǎng)絡(luò)空間、域名與空間、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。

根據(jù)傳說(shuō)中的Venkat Subramaniam,多態(tài)是面向?qū)ο缶幊讨凶钪匾母拍睢?多態(tài)性(或?qū)ο蟾鶕?jù)其類型執(zhí)行特殊操作的能力)使Java代碼具有靈活性。 諸如 四個(gè)人幫 之類的設(shè)計(jì)模式(例如Command,Observer,Decorator,Strategy和許多其他模式)都使用某種形式的多態(tài)性。 精通此概念可極大地提高你思考解決編程難題的能力。

Juggy:
public abstract class JavaMascot {
    public abstract void executeAction();}public class Duke extends JavaMascot {
    @Override
    public void executeAction() {
        System.out.println("Punch!");
    }}public class Juggy extends JavaMascot {
    @Override
    public void executeAction() {
        System.out.println("Fly!");
    }}public class JavaMascotTest {
    public static void main(String... args) {
        JavaMascot dukeMascot = new Duke();
        JavaMascot juggyMascot = new Juggy();
        dukeMascot.executeAction();
        juggyMascot.executeAction();
    }}
 Punch!Fly!

多態(tài)性的接口和繼承
借助此Java Challenger,我們將致力于多態(tài)性與繼承之間的關(guān)系。 要記住的主要事情是多態(tài)性需要繼承或接口實(shí)現(xiàn)。 你可以在下面的示例中看到這一點(diǎn),其中包括Duke和
由于其特定的實(shí)現(xiàn)方式,Duke和Juggy的動(dòng)作都將被執(zhí)行。

方法是否重載了多態(tài)性?
許多程序員對(duì)多態(tài)與方法重寫和方法重載之間的關(guān)系感到困惑。 實(shí)際上,只有方法重載才是真正的多態(tài)性。 重載使用相同的方法名稱,但參數(shù)不同。 多態(tài)性是一個(gè)廣義術(shù)語(yǔ),因此始終會(huì)有關(guān)于該主題的討論。

多態(tài)性的目的是什么?
使用多態(tài)的最大優(yōu)點(diǎn)和目的是將客戶端類與實(shí)現(xiàn)代碼分離。 客戶端類無(wú)需進(jìn)行硬編碼,而是接收實(shí)現(xiàn)以執(zhí)行必要的操作。 這樣,客戶端類就足夠了解執(zhí)行其動(dòng)作的知識(shí),這是松耦合的示例。

為了更好地了解多態(tài)的目的,請(qǐng)看一下

public abstract class SweetProducer {
    public abstract void produceSweet();}public class CakeProducer extends SweetProducer {
    @Override
    public void produceSweet() {
        System.out.println("Cake produced");
    }}public class ChocolateProducer extends SweetProducer {
    @Override
    public void produceSweet() {
        System.out.println("Chocolate produced");
    }}public class CookieProducer extends SweetProducer {
    @Override
    public void produceSweet() {
        System.out.println("Cookie produced");
    }}public class SweetCreator {
    private List sweetProducer;
    public SweetCreator(List sweetProducer) {
        this.sweetProducer = sweetProducer;
    }
    public void createSweets() {
        sweetProducer.forEach(sweet -> sweet.produceSweet());
    }}public class SweetCreatorTest {
    public static void main(String... args) {
        SweetCreator sweetCreator = new SweetCreator(Arrays.asList(new CakeProducer(),
                new ChocolateProducer(), new CookieProducer()));
        sweetCreator.createSweets();
    }}

在此示例中,你可以看到SweetCreator類僅知道SweetProducer類。 它不知道每個(gè)甜食的實(shí)現(xiàn)。 這種分離使我們可以靈活地更新和重用我們的類,并使代碼易于維護(hù)。 設(shè)計(jì)代碼時(shí),請(qǐng)始終尋找使代碼盡可能靈活和可維護(hù)的方法。 多態(tài)性是用于這些目的的一種非常強(qiáng)大的技術(shù)。

提示:@Override注釋使程序員有義務(wù)使用必須重寫的相同方法簽名。 如果未重寫該方法,則將出現(xiàn)編譯錯(cuò)誤。
方法覆蓋中的協(xié)變返回類型

如果它是協(xié)變類型,則可以更改覆蓋方法的返回類型。 協(xié)變量類型基本上是返回類型的子類。 考慮一個(gè)例子:

public abstract class JavaMascot {
    abstract JavaMascot getMascot();}public class Duke extends JavaMascot {
    @Override
    Duke getMascot() {
        return new Duke();
    }}

由于Duke是JavaMascot,因此我們可以在覆蓋時(shí)更改返回類型。

Java核心類的多態(tài)性
我們一直在核心Java類中使用多態(tài)。 一個(gè)非常簡(jiǎn)單的示例是當(dāng)我們實(shí)例化ArrayList類時(shí),將List接口聲明為一種類型:

List list = new ArrayList<>();

為了進(jìn)一步講解,請(qǐng)考慮使用Java Collections API且無(wú)多態(tài)性的以下代碼示例:

public class ListActionWithoutPolymorphism {
   // Example without polymorphism
    void executeVectorActions(Vector vector) {/* Code repetition here*/}
    void executeArrayListActions(ArrayList arrayList) {/*Code repetition here*/}
    void executeLinkedListActions(LinkedList linkedList) {/* Code repetition here*/}
    void executeCopyOnWriteArrayListActions(CopyOnWriteArrayList copyOnWriteArrayList)
        { /* Code repetition here*/}}public class ListActionInvokerWithoutPolymorphism {
        listAction.executeVectorActions(new Vector<>());
        listAction.executeArrayListActions(new ArrayList<>());
        listAction.executeLinkedListActions(new LinkedList<>());
        listAction.executeCopyOnWriteArrayListActions(new CopyOnWriteArrayList<>());}

丑陋的代碼,不是嗎? 想象一下要維護(hù)它! 現(xiàn)在來(lái)看具有多態(tài)性的相同示例

public static void main(String … polymorphism) {ListAction listAction = new ListAction();   
    listAction.executeListActions();}public class ListAction {
    void executeListActions(List list) {
        // Execute actions with different lists
    }}public class ListActionInvoker {
    public static void main(String... masterPolymorphism) {
        ListAction listAction = new ListAction();
        listAction.executeListActions(new Vector<>());
        listAction.executeListActions(new ArrayList<>());
        listAction.executeListActions(new LinkedList<>());
        listAction.executeListActions(new CopyOnWriteArrayList<>());
    }}

多態(tài)性的好處是靈活性和可擴(kuò)展性。 除了創(chuàng)建幾種不同的方法外,我們可以只聲明一個(gè)接收通用List類型的方法。

在多態(tài)方法調(diào)用中調(diào)用特定方法
可以在多態(tài)調(diào)用中調(diào)用特定的方法,但是這樣做會(huì)犧牲靈活性。 這是一個(gè)例子:

public abstract class MetalGearCharacter {
    abstract void useWeapon(String weapon);}public class BigBoss extends MetalGearCharacter {
    @Override
    void useWeapon(String weapon) {
        System.out.println("Big Boss is using a " + weapon);
    }
   void giveOrderToTheArmy(String orderMessage) {
        System.out.println(orderMessage);
    }}public class SolidSnake extends MetalGearCharacter {
    void useWeapon(String weapon) {
        System.out.println("Solid Snake is using a " + weapon);
    }}public class UseSpecificMethod {
    public static void executeActionWith(MetalGearCharacter metalGearCharacter) {
        metalGearCharacter.useWeapon("SOCOM");
    // The below line wouldn't work
        // metalGearCharacter.giveOrderToTheArmy("Attack!");
        if (metalGearCharacter instanceof BigBoss) {
            ((BigBoss) metalGearCharacter).giveOrderToTheArmy("Attack!");
        }
    }public static void main(String... specificPolymorphismInvocation) {
        executeActionWith(new SolidSnake());
        executeActionWith(new BigBoss());
    }}

我們?cè)谶@里使用的技術(shù)是廣播或在運(yùn)行時(shí)故意更改對(duì)象類型。
請(qǐng)注意,只有在將通用類型轉(zhuǎn)換為特定類型時(shí)才可以調(diào)用特定方法。 一個(gè)很好的類比是對(duì)編譯器明確地說(shuō):“嘿,我知道我在這里做什么,所以我將對(duì)象轉(zhuǎn)換為特定類型并使用特定方法?!?/p>

參考上面的示例,一個(gè)重要原因是編譯器拒絕接受特定的方法調(diào)用:正在傳遞的類可能是SolidSnake。 在這種情況下,編譯器無(wú)法確保MetalGearCharacter的每個(gè)子類都聲明了giveOrderToTheArmy方法。

保留關(guān)鍵字的實(shí)例
請(qǐng)注意實(shí)例化的保留字。 在調(diào)用特定方法之前,我們?cè)儐?wèn)了MetalGearCharacter是否為BigBoss的“實(shí)例”。 如果不是BigBoss實(shí)例,我們將收到以下異常消息:

線程“主”中的異常java.lang.ClassCastException:com.javaworld.javachallengers.polymorphism.specificinvocation.SolidSnake無(wú)法轉(zhuǎn)換為com.javaworld.javachallengers.polymorphism.specificinvocation.BigBoss

超級(jí)保留關(guān)鍵字
如果我們想引用Java超類的屬性或方法怎么辦? 在這種情況下,我們可以使用超級(jí)保留字。 例如:

public class JavaMascot {
  void executeAction() {
    System.out.println("The Java Mascot is about to execute an action!");
  }}public class Duke extends JavaMascot {
  @Override
  void executeAction() {
    super.executeAction();
    System.out.println("Duke is going to punch!");
  }
  public static void main(String... superReservedWord) {
    new Duke().executeAction();
  }}

在Duke的executeAction方法中使用保留字super調(diào)用超類方法。 然后我們從杜克(Duke)執(zhí)行特定操作。 因此,我們可以在下面的輸出中看到兩條消息:

Java Mascot即將執(zhí)行一個(gè)動(dòng)作!Duke要出拳了!

接受多態(tài)挑戰(zhàn)!
讓我們嘗試一下你對(duì)多態(tài)性和繼承的了解。首先,請(qǐng)仔細(xì)分析以下代碼:

public class PolymorphismChallenge {
    static abstract class Simpson {
        void talk() {
            System.out.println("Simpson!");
        }
        protected void prank(String prank) {
            System.out.println(prank);
        }
    }
    static class Bart extends Simpson {
        String prank;
        Bart(String prank) { this.prank = prank; }
        protected void talk() {
            System.out.println("Eat my shorts!");
        }
        protected void prank() {
            super.prank(prank);
            System.out.println("Knock Homer down");
        }
    }
    static class Lisa extends Simpson {
        void talk(String toMe) {
            System.out.println("I love Sax!");
        }
    }
    public static void main(String... doYourBest) {
        new Lisa().talk("Sax :)");
        Simpson simpson = new Bart("D'oh");
        simpson.talk();
        Lisa lisa = new Lisa();
        lisa.talk();
        ((Bart) simpson).prank();
    }}

你怎么看? 最終輸出將是什么? 不要使用IDE來(lái)解決這個(gè)問(wèn)題! 關(guān)鍵是要提高代碼分析技能,因此請(qǐng)嘗試自己確定輸出。

了解多態(tài)
對(duì)于以下方法調(diào)用:

new Lisa().talk("Sax :)");

輸出為“ I love Sax!”,這是因?yàn)槲覀冋谙蛟摲椒▊鬟f字符串,而Lisa具有該方法。
對(duì)于下一個(gè)調(diào)用:

Simpson simpson = new Bart("D'oh");
simpson.talk();

輸出將是“Eat my shorts!” 這是因?yàn)槲覀冋谑褂肂art實(shí)例化Simpson類型。
現(xiàn)在檢查一下,這有點(diǎn)棘手:

Lisa lisa = new Lisa();
lisa.talk();

在這里,我們使用帶有繼承的方法重載。 我們沒(méi)有將任何內(nèi)容傳遞給talk方法,這就是調(diào)用Simpsontalk方法的原因。 在這種情況下,輸出將是:

"Simpson!"

這里還有一個(gè):

((Bart) simpson).prank();

在這種情況下,當(dāng)我們使用new Bart(“ D'oh”);實(shí)例化Bart類時(shí),會(huì)傳遞惡作劇字符串。 在這種情況下,首先將調(diào)用super.prank方法,然后是來(lái)自Bart的特定惡作劇方法。 輸出將是:

"D'oh""Knock Homer down"

視頻挑戰(zhàn)! 調(diào)試Java多態(tài)性和繼承

調(diào)試是完全吸收編程概念并改善代碼的最簡(jiǎn)單方法之一。 在此視頻中,你可以在調(diào)試和解釋Java多態(tài)性挑戰(zhàn)時(shí)繼續(xù)學(xué)習(xí):

多態(tài)性的常見錯(cuò)誤
認(rèn)為無(wú)需使用強(qiáng)制轉(zhuǎn)換就可以調(diào)用特定方法是一個(gè)常見的錯(cuò)誤。

另一個(gè)錯(cuò)誤是不確定多態(tài)實(shí)例化類時(shí)將調(diào)用哪種方法。 請(qǐng)記住,要調(diào)用的方法是創(chuàng)建的實(shí)例的方法。
還要記住,方法重載不是方法重載。

如果參數(shù)不同,則無(wú)法覆蓋方法。 如果返回類型是超類方法的子類,則可以更改重寫方法的返回類型。

喜歡這篇文章的可以點(diǎn)個(gè)贊,歡迎大家留言評(píng)論,記得關(guān)注我,每天持續(xù)更新技術(shù)干貨、職場(chǎng)趣事、海量面試資料等等
?> 如果你對(duì)java技術(shù)很感興趣也可以交流學(xué)習(xí),共同學(xué)習(xí)進(jìn)步。?
不要再用"沒(méi)有時(shí)間“來(lái)掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來(lái)的自己一個(gè)交代

文章寫道這里,歡迎完善交流。最后奉上近期整理出來(lái)的一套完整的java架構(gòu)思維導(dǎo)圖,分享給大家對(duì)照知識(shí)點(diǎn)參考學(xué)習(xí)。有更多JVM、MySQL、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、redis、ELK、Git等Java干貨

關(guān)于多態(tài)性要記住什么
??創(chuàng)建的實(shí)例將確定使用多態(tài)時(shí)將調(diào)用哪種方法。
??@ Override注釋使程序員有義務(wù)使用覆蓋的方法; 否則,將出現(xiàn)編譯器錯(cuò)誤。
?多態(tài)可以與普通類,抽象類和接口一起使用。
??大多數(shù)設(shè)計(jì)模式取決于某種形式的多態(tài)性。
??在多態(tài)子類中使用特定方法的唯一方法是使用強(qiáng)制轉(zhuǎn)換。
??可以使用多態(tài)性在代碼中設(shè)計(jì)功能強(qiáng)大的結(jié)構(gòu)。
??運(yùn)行測(cè)試。 這樣做,你將能夠掌握這個(gè)強(qiáng)大的概念!

精選Java中的多態(tài)和繼承


當(dāng)前名稱:精選Java中的多態(tài)和繼承
網(wǎng)站鏈接:http://weahome.cn/article/pddhsp.html

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部