<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ply

    吞噬黑暗
    posts - 1, comments - 11, trackbacks - 0, articles - 13
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    理解多態AND理解父類引用指向子類對象

    Posted on 2011-12-01 22:24 ply 閱讀(2841) 評論(0)  編輯  收藏

    從對象的內存角度來理解試試.

    假設現在有一個父類Father,它里面的變量需要占用1M內存.有一個它的子類Son,它里面的變量需要占用0.5M內存.

    現在通過代碼來看看內存的分配情況:

    Father f = new Father();//系統將分配1M內存.

    Son s = new Son();//系統將分配1.5M內存.


    因為子類中有一個隱藏的引用super會指向父類實例,所以在實例化子類之前會先實例化一個父類,也就是說會先執行父類的構造函數.

    由于s中包含了父類的實例,所以s可以調用父類的方法.


    Son s1 = s;//s1指向那1.5M的內存.(可以理解為就是:子類引用指向子類對象)


    Father f1 = (Father)s;//這時f1會指向那1.5M內存中的1M內存,即是說,f1只是指向了s中實例的父類實例對象,所以f1只能調用父類的方法(存儲在1M內存中),而不能調用子類的方法(存儲在0.5M內存中).


    Son s2 = (Son)f;//這句代碼運行時會報ClassCastException.因為f中只有1M內存,而子類的引用都必須要有1.5M的內存,所以無法轉換.


    Son s3 = (Son)f1;//這句可以通過運行,這時s3指向那1.5M的內存.由于f1是由s轉換過來的,所以它是有1.5M的內存的,只是它指向的只有1M內存.

     


    示例:

    class Father{

    void print(){};

    }


    class Son extends Father{

    void print(){System.out.println("子類中!");}

    void show(){System.out.println("show 中!");}

    }


    class Demo{

    public static void main(String args[]){

    Father obj=new Son();

    obj.print();

    obj.show();  //這個調用會報錯!

    }

    }


    1 .如果你想實現多態,那么必須有三個條件,父類引用,子類對象,方法覆蓋

    你這里如果Fathor類有一個show()方法,那么形成方法覆蓋,那么此時就可以這么寫:obj.show(),此刻形成了多態.

    2. 沒有方法覆蓋,那你這里只能解釋為父類引用去訪問一個子類的方法,當然,父類引用沒有這么大范圍的權限,當然會報錯

    PS:多態實際上是一種機制,在編譯時刻,會生成一張虛擬表,來記錄所有覆蓋的方法,沒有被覆蓋的方法是不會記錄到這張表的.

    若一個父類引用調用了沒有覆蓋的子類方法,那么是不符合該表的,那么編譯時刻就會報錯.

    在執行程序的時候,虛擬機會去這張虛擬表中找覆蓋的方法,比如引用中實際上存的是一個子類對象引用,那么就會去找子類中的相應的覆蓋的方法來執行

    定義一個父類類型的引用指向一個子類的對象既可以使用子類強大的功能,又可以抽取父類的共性。

    所以,父類類型的引用可以調用父類中定義的所有屬性和方法,而對于子類中定義而父類中沒有的方法,它是無可奈何的;

    同時,父類中的一個方法只有在在父類中定義而在子類中沒有重寫的情況下,才可以被父類類型的引用調用;

    對多態的理解:多態體現在繼承中,所以需要有繼承關系,然后子類要重寫父類方法,最后父類指向子類(父類本身具有一些方法,這些方法被子類重寫了,但調用這些方法時,會自動調子類重寫的那些)。

    多態具體表現在重寫和重載,多態就是類的多種表現方式,比如同名不同參,子類重寫父類。

    看下面這段程序:

    class Father{

        public void func1(){

            func2();

        }


        //這是父類中的func2()方法,因為下面的子類中重寫了該方法

        //所以在父類類型的引用中調用時,這個方法將不再有效

        //取而代之的是將調用子類中重寫的func2()方法

        public void func2(){

            System.out.println("AAA");

        }

    }

     

    class Child extends Father{

        //func1(int i)是對func1()方法的一個重載

        //由于在父類中沒有定義這個方法,所以它不能被父類類型的引用調用

        //所以在下面的main方法中child.func1(68)是不對的

        public void func1(int i){

            System.out.println("BBB");

        }


        //func2()重寫了父類Father中的func2()方法

        //如果父類類型的引用中調用了func2()方法,那么必然是子類中重寫的這個方法

        public void func2(){

            System.out.println("CCC");

        }

    }


    public class PolymorphismTest {

        public static void main(String[] args) {

            Father child = new Child();

            child.func1();//打印結果將會是什么?  

        }

    }


      
    上面的程序是個很典型的多態的例子。子類Child繼承了父類Father,并重載了父類的func1()方法,重寫了父類的func2()方法。重載后的func1(int
    i)和func1()不再是同一個方法,由于父類中沒有func1(int i),那么,父類類型的引用child就不能調用func1(int
    i)方法。而子類重寫了func2()方法,那么父類類型的引用child在調用該方法時將會調用子類中重寫的func2()。


        那么該程序將會打印出什么樣的結果呢?

        很顯然,應該是“CCC”。







    變量是不存在重寫覆蓋的!

    public class A { int a = 1; }

    public class B extends A { int a = 2; }


    測試類里調用了這個方法void compare(){

    if(super.a == this.a)

    System.out.println("not overrided");

    else

    System.out.println("overrided");}

    控制臺出來的是overrided

     類中的屬性是沒有多態性的,即你在引用上面使用屬性時,系統只會去找引用的靜態類型中的那個屬性,而與它的實際類型無關。

    靜態方法也是沒有多態性的。


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 最近2019中文字幕免费看最新| 最近中文字幕大全免费版在线| 国产精彩免费视频| 91亚洲国产在人线播放午夜| 久久久免费的精品| 亚洲精品乱码久久久久久下载 | 亚洲人成电影在在线观看网色| 黄视频在线观看免费| 国产亚洲美女精品久久久| 国产高潮久久免费观看| 亚洲精品tv久久久久久久久| 男的把j放进女人下面视频免费| 亚洲人成电影在线天堂| 麻豆一区二区免费播放网站 | 老司机精品视频免费| 免费人成网站在线高清| eeuss免费天堂影院| 亚洲人成亚洲精品| 在线看免费观看AV深夜影院| 最新国产精品亚洲| 亚洲无码高清在线观看| 99久久国产精品免费一区二区 | 亚洲精品无码专区| 亚洲AV无码乱码精品国产| 成在线人视频免费视频| 亚洲福利秒拍一区二区| 四虎成人免费大片在线| 一级女性全黄生活片免费看| 亚洲AV日韩AV永久无码绿巨人| 很黄很色很刺激的视频免费| 美女黄网站人色视频免费| 国产亚洲真人做受在线观看| 天天影院成人免费观看| 羞羞漫画页面免费入口欢迎你| 久久精品亚洲综合一品| 免费无码成人AV片在线在线播放| 搜日本一区二区三区免费高清视频 | 免费福利在线视频| 亚洲国产日韩精品| 亚洲乱码日产一区三区| 在线v片免费观看视频|