0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

全面講解?向?qū)ο缶幊倘?特性 2

jf_78858299 ? 來源:小牛呼嚕嚕 ? 作者:小牛呼嚕嚕 ? 2023-02-09 14:25 ? 次閱讀

我們來看上面part1部分:

Cat cat_ = new Cat();
        cat_.eat();
        cat_.sleep();
        cat_.work();

結(jié)果:

吃魚

貓會睡懶覺。

動物可以幫助人類干活!

cat_.work(); 這處繼承了父類Animal的方法,還是很好理解的

我們接著看part2:

Animal cat=new Cat();
        cat.eat();
        cat.work();
        cat.sleep();//此處編譯會報錯。

        Animal dog=new Dog();
        dog.eat();//結(jié)果為:吃骨頭。此處調(diào)用子類的同名方法。

這塊就比較特殊了,我們一句句來看

Animal cat=new Cat(); 像這種這個 父類引用指向子類對象,這種現(xiàn)象叫做: "向上轉(zhuǎn)型" ,也被稱為 多態(tài)的引用 。

cat.sleep();這句 編譯器會提示 編譯報錯。表明:當(dāng)我們當(dāng)子類的對象作為父類的引用使用時,只能訪問子類中和父類中都有的方法,而無法去訪問子類中特有的方法

值得注意的是:向上轉(zhuǎn)型是安全的。但是缺點是:一旦向上轉(zhuǎn)型,子類會丟失子類的擴展方法,其實就是 子類中原本特有的方法就不能再被調(diào)用了。所以cat.sleep()這句會編譯報錯。

cat.eat();這句的結(jié)果打?。撼贼~。程序這塊調(diào)用我們Cat定義的方法。

cat.work();這句的結(jié)果打?。簞游锟梢詭椭祟惛苫?!我們上面Cat類沒有定義work方法,但是卻使用了父類的方法,這是不是很神奇。其實此處調(diào)的是父類的同名方法

Animal dog=new Dog();dog.eat();這句的結(jié)果打印為:吃骨頭。此處調(diào)用子類的同名方法。

由此我們可以知道當(dāng)發(fā)生向上轉(zhuǎn)型,去調(diào)用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,再去調(diào)用子類的同名方法。如果子類沒有同名方法,會再次去調(diào)父類中的該方法

向上轉(zhuǎn)型

我們現(xiàn)在知道了 向上轉(zhuǎn)型時會丟失子類的擴展方法,哎,但我們就是想找回來,這可咋辦?

向下轉(zhuǎn)型可以幫助我們,找回曾經(jīng)失去的

我們來看part3:

Cat cat_real = (Cat)cat;  //注意 此處的cat 對應(yīng)上面父類Animal,可不是子類
    cat_real.sleep();

Cat cat = (Cat)cat; cat222.sleep(); 這個向下轉(zhuǎn)型非常像"強轉(zhuǎn)"。

打印的結(jié)果:貓會睡懶覺。此處又能調(diào)用了 子類Cat 的 sleep()方法了。

一道簡單的面試題

我們再來看一道有意思的題,來強化理解

public class Main {
    
    static class Animal{
        int weight = 10;

        public void print() {
            System.out.println("this Animal Print:" + weight);
        }

        public Animal() {
            print();
        }
    }

    static class Dog extends Animal {
        int weight = 20;

        @Override
        public void print() {
            System.out.println("this Dog Print:" + weight);
        }

        public Dog() {
            print();
        }
    }

    public static void main(String[] args) {
        Dog dog = new Dog();

        System.out.println("---------------");
        Animal dog222 = new Dog();
        Dog dog333 =  (Dog)dog222;
        
        System.out.println("---------------");
        Dog dog444 = (Dog)new Animal();

    }
}

執(zhí)行結(jié)果:

this Dog Print:0
this Dog Print:20
---------------
this Dog Print:0
this Dog Print:20
---------------
this Animal Print:10
Exception in thread "main" java.lang.ClassCastException: com.zj.Main$Animal cannot be cast to com.zj.Main$Dog
 at com.zj.Main.main(Main.java:15)

做對了嘛,不對的話,復(fù)制代碼去idea中debug看看

我們先看第一部分

Dog dog = new Dog();

程序內(nèi)部的執(zhí)行順序:

  1. 先 初始化 父類Animal 的屬性 int weight=10
  2. 然后 調(diào)用父類Animal的構(gòu)造方法,執(zhí)行print()
  3. 實際調(diào)用子類Dog的print()方法,打?。?code>this Dog Print:0,由于此時的子類屬性weight 并未初始化
  4. 初始化 子類Dog 的屬性 int weight=20
  5. 調(diào)用 子類Dog的構(gòu)造方法,執(zhí)行print()
  6. 實際調(diào)用當(dāng)前類的print()方法,打印this Dog Print:20

其中有幾處我們需要注意一下:實例化子類dog,程序會去默認優(yōu)先實例化父類,即子類實例化時會隱式傳遞Dog的this調(diào)用父類構(gòu)造器進行初始化工作,這個和JVM的雙親委派機制有關(guān),這里就不展開講了,先挖個坑,以后再來填

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
收藏 人收藏

    評論

    相關(guān)推薦

    嵌入式C語言面向對象編程---多態(tài)

    前兩篇文章主要講述了 C 語言面向對象編程– 封裝和繼承。本篇文章繼續(xù)來討論一下,如何使用 C 語言實現(xiàn)面向對象編程的另一個重要特性:多態(tài)。
    發(fā)表于 10-31 14:41 ?1016次閱讀

    Python的面向對象編程詳解

    一般編程可分為面向過程編程,和面向對象編程。Python的面向對象編程,與Java的面向
    發(fā)表于 09-04 16:35 ?580次閱讀
    Python的面向<b class='flag-5'>對象</b><b class='flag-5'>編程</b>詳解

    每日一教labview視頻教程【12.15】labview面向對象編程(上)

    面向對象編程視頻:專家從類開始進行講解,詳細說明了如何進行面向對象編程。http://yunpan.cn/lk/480ep1p
    發(fā)表于 12-15 10:35

    利用LabVIEW工程庫實現(xiàn)面向對象編程

    。VI Scripting技術(shù)也是LabVIEW的新特性。利用它可以直接在LabVIEW中解析或更改LabVIEW VI。. LabVIEW面向對象編程的具體實現(xiàn)方法我們可以把一組相
    發(fā)表于 12-06 12:41

    編程魔法師大思想視頻宣傳片

    ,講解了單片機裸編程項目的設(shè)計實現(xiàn)過程,并通過一只電機對象到兩只電機對象的設(shè)計演變過程,深入講解了數(shù)碼分離、線程實現(xiàn)、
    發(fā)表于 04-23 21:46

    面向對象編程及其特性 精選資料分享

    編程語言分為面向過程編程、函數(shù)式編程和面向對象編程。其實python就是一種面向對象
    發(fā)表于 07-21 08:38

    面向對象編程介紹

    目錄一、面向對象編程介紹1.面向過程編程2.函數(shù)式編程3.面向對象
    發(fā)表于 12-13 07:22

    C++面向對象多線程編程 (pdf電子版)

    C++面向對象多線程編程共分13章,全面講解構(gòu)建多線程架構(gòu)與增量多線程編程技術(shù)。第1章介紹了
    發(fā)表于 09-25 09:39 ?0次下載

    對象特性的測定

    對象特性的測定 一、 實驗?zāi)康?、通過實驗了解對象的靜態(tài)和動態(tài)特性2、掌握對象靜態(tài)和動態(tài)
    發(fā)表于 05-17 10:53 ?14次下載

    面向對象編程練習(xí)

    實驗 3 面向對象編程練習(xí) 一、實驗?zāi)康?    通過編程和上機實驗理解 Java 語言是如何體現(xiàn)面向對象編程
    發(fā)表于 09-23 18:57 ?3054次閱讀

    LabVIEW 網(wǎng)絡(luò)講壇第四季:面向對象編程的應(yīng)用

    本視頻主要講解了基本概念,以及面向對象編程在LabVIEW中的應(yīng)用。
    的頭像 發(fā)表于 06-25 02:46 ?2904次閱讀
    LabVIEW 網(wǎng)絡(luò)講壇第四季:面向<b class='flag-5'>對象</b>的<b class='flag-5'>編程</b>的應(yīng)用

    Labview面向對象編程快速入門教程

    在面向對象編程中, 類用來表示通用特性。 例如,假設(shè)有一個描述汽車的類。 類中定義了各種汽車的通用特性。對象是類的特定實例。汽車類的一個
    發(fā)表于 07-31 08:00 ?82次下載
    Labview面向<b class='flag-5'>對象</b><b class='flag-5'>編程</b>快速入門教程

    西門子PLC面向對象編程的邏輯

    面向對象編程是計算機高級語言的一種高級編程模式,這種設(shè)計思想也可以應(yīng)用于工業(yè)控制系統(tǒng)的plc程序中。雖然我們無法實現(xiàn)面向對象編程的許多優(yōu)秀
    發(fā)表于 12-28 14:22 ?1474次閱讀

    全面講解?對象編程?特性 1

    把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏。封裝是面向對象的特征之一,是對象和類概念的主要特性。 > 通俗地說,一個類
    的頭像 發(fā)表于 02-09 14:24 ?366次閱讀

    西門子PLC面向對象編程

    面向對象編程是計算機高級語言的一種高級編程模式,這種設(shè)計思想也可以應(yīng)用于工業(yè)控制系統(tǒng)的plc程序中。雖然我們 無法實現(xiàn)面向對象編程的許多優(yōu)
    發(fā)表于 04-17 11:41 ?7次下載
    西門子PLC面向<b class='flag-5'>對象</b><b class='flag-5'>編程</b>