隨筆-3  評論-2  文章-0  trackbacks-0

          第一點:

          那就是

          ?????????1.如果子類覆蓋了父類的方法,那么子類對象調用該方法時,被該方法修改的類級別變量是子類的變量。
          ?????????2.如果子類沒有覆蓋父類方法,而直接調用父類的方法,那么被該方法修改的類級別變量是父類的變量。

          1則如下例:

          public ? class ?Temp {
          ??
          public ? static ? void ?main(String?args[]) {
          ????b?bb?
          = ? new ?b();
          ????bb.fuqin();
          ??}

          }

          class ?a {
          ??
          public ?String?s? = ? " fuqin " ;
          ??
          public ? void ?fuqin() {
          ????System.out.println(s);
          ??}

          }

          class ?b? extends ?a {
          ??
          public ?String?s? = ? " erzi " ;
          ??
          public ? void ?fuqin() {
          ????System.out.println(s);
          ??}

          }

          // 結果為erzi


          2.則如下例:

          public ? class ?Temp {
          ??
          public ? static ? void ?main(String?args[]) {
          ????b?bb?
          = ? new ?b();
          ????bb.fuqin();
          ??}

          }

          class ?a {
          ??
          public ?String?s? = ? " fuqin " ;
          ??
          public ? void ?fuqin() {
          ????System.out.println(s);
          ??}

          }

          class ?b? extends ?a {
          ??
          public ?String?s? = ? " erzi " ;
          ??
          public ? void ?erzi() {
          ????System.out.println(s);
          ??}

          }

          // 結果為fuqin

          第二點:

          那就是對“覆蓋(override)”和“重載(overload)”以及重建的概念的清晰。
          先聲明一下:重建就是寫一個新的方法。
          如下例:
          下面這個叫覆蓋

          public ? class ?Temp? {
          ??
          public ? static ? void ?main(String[]?args)? {
          ????Sub?sub?
          = ? new ?Sub();
          ????sub.plus(
          2 );
          ????System.out.println(sub.i);
          ??}

          }


          class ?Super? {
          ??
          protected ? int ?i;
          ??
          void ?plus( int ?i)? {
          ????
          this .i? += ?i;
          ??}

          }


          class ?Sub
          ????
          extends ?Super? {
          ??
          protected ? int ?i? = ? 1 ;
          ??
          void ?plus( int ?i) {
          ????
          this .i = i + 5 ;
          ??}

          }



          下面這個叫重建,不是重載:

          public ? class ?Temp? {
          ??
          public ? static ? void ?main(String[]?args)? {
          ????Sub?sub?
          = ? new ?Sub();
          ????sub.plus(
          2 );
          ????sub.plus(
          2 , 2 );
          ????System.out.println(sub.i);
          ????System.out.println(((Super)sub).i);
          ??}

          }


          class ?Super? {
          ??
          protected ? int ?i;
          ??
          void ?plus( int ?i)? {
          ????
          this .i? += ?i;
          ??}

          }


          class ?Sub
          ????
          extends ?Super? {
          ??
          protected ? int ?i? = ? 1 ;
          ??
          void ?plus( int ?i, int ?j) {
          ????
          this .i = i + j;
          ??}

          ??
          void ?jian( int ?i) {
          ????
          this .i = this .i - i;
          ??}

          }



          第三點:

          那就是通常所說的“繼承后使用多態”、“動態方法調度”、“運行時類型識別”了。先不要被上面的術語搞昏頭哦:-)
          可以總結為以下兩條:
          1.默認狀態(和強制類型轉換狀態相區別)下,該對象(sub)能且只能調用父類方法和父類變量(調用子類方法時會出現編譯期錯誤)。此種情況下,還有兩種不同的情況:
          ?????????? ▲被調用方法是被子類覆蓋的方法,這時父類變量不能被該方法修改。【注1】
          ?????????? ▲被調用方法沒有被子類覆蓋,這時父類變量可以被該方法修改。
          看看下面的代碼,注意1~5處。

          public ? class ?Temp? {
          ??
          public ? static ? void ?main(String[]?args)? {
          ????Super?sub?
          = ? new ?Sub();
          ????System.out.println(sub.i);
          // 打印結果為0----------------------------------------------1
          ????sub.plus( 3 ); // 默認狀態下調用被覆蓋了的父類方法------------------------------2
          ????System.out.println(sub.i); // 打印結果為0----------------------------------------------3
          ????sub.print(); // 默認狀態下調用沒有被覆蓋的父類方法----------------------------4
          ????System.out.println(sub.i); // 打印結果為5:-------------------------------------------5
          ??}

          }


          class ?Super? {
          ??
          protected ? int ?i = 0 ;
          ??
          void ?plus( int ?i)? {
          ????
          this .i? = 3 ;
          ??}

          ??
          void ?print() {
          ????
          this .i = 5 ;
          ??}

          }


          class ?Sub
          ????
          extends ?Super? {
          ??
          protected ? int ?i? = ? 1 ;
          ??
          void ?plus( int ?i)? {
          ????
          this .i? = ?i? + ? 8 ;
          ??}


          ??
          void ?plus( int ?i,? int ?j)? {
          ????
          this .i? = ?i? + ?j;
          ??}


          ??
          void ?reduce( int ?i)? {
          ????
          this .i? = ? this .i? - ?i;
          ??}

          }


          2.強制類型轉換狀態下【注2】,該對象(sub)能且只能調用其子類方法和子類變量(這時被修改的就是子類變量 了)。
          ??????? 此種情況下,也有兩種不同情況:
          ????????????????▲調用方法時強制轉換,比如下面的((Sub)sub).plus(int i);
          ??????????????? ▲調用變量時強制轉化,比如下面的System.out.println(((Sub)sub).i);
          ??????? 看看下面的代碼,注意6、7處:

          public ? class ?Temp? {
          ??
          public ? static ? void ?main(String[]?args)? {
          ????Super?sub?
          = ? new ?Sub();
          ????((Sub)sub).plus(
          3 ); // 調用方法時強制轉換----------------------------------------------6
          ????System.out.println(((Sub)sub).i); // 調用變量時的強制轉換,打印結果11------7
          ??}

          }


          class ?Super? {
          ??
          protected ? int ?i = 0 ;
          ??
          void ?plus( int ?i)? {
          ????
          this .i? = 3 ;
          ??}

          ??
          void ?print() {
          ????
          this .i = 5 ;
          ??}

          }


          class ?Sub
          ????
          extends ?Super? {
          ??
          protected ? int ?i? = ? 1 ;
          ??
          void ?plus( int ?i)? {
          ????
          this .i? = ?i? + ? 8 ;
          ??}


          ??
          void ?plus( int ?i,? int ?j)? {
          ????
          this .i? = ?i? + ?j;
          ??}


          ??
          void ?reduce( int ?i)? {
          ????
          this .i? = ? this .i? - ?i;
          ??}

          }



          【注1】這種情況下,把該對象強制轉換為子類對象時,可以發現,如果子類中覆蓋了父類的方法,那么子類的變量 被改變了。如下例中。
          【注2】對父類強制轉換的結果和默認狀態下是相同的,所以,這里只討論對子類強制轉換。

          ?????? 下面的兩個例子混合了上述情況,體驗一下,注意8~17處。
          例1.

          public ? class ?Temp? {
          ??
          public ? static ? void ?main(String[]?args)? {
          ????Super?sub?
          = ? new ?Sub();
          ????sub.plus(
          3 ); // 默認狀態下調用被覆蓋了的父類方法---------------------------------8
          ????System.out.println(sub.i); // 調用變量時強制轉化,打印結果為0-----------------9
          ????System.out.println(((Sub)sub).i); // 打印結果為11--------------------------------------10
          ??}

          }


          class ?Super? {
          ??
          protected ? int ?i = 0 ;
          ??
          void ?plus( int ?i)? {
          ????
          this .i? = 3 ;
          ??}

          ??
          void ?print() {
          ????
          this .i = 5 ;
          ??}

          }


          class ?Sub
          ????
          extends ?Super? {
          ??
          protected ? int ?i? = ? 1 ;
          ??
          void ?plus( int ?i)? {
          ????
          this .i? = ?i? + ? 8 ;
          ??}


          ??
          void ?plus( int ?i,? int ?j)? {
          ????
          this .i? = ?i? + ?j;
          ??}


          ??
          void ?reduce( int ?i)? {
          ????
          this .i? = ? this .i? - ?i;
          ??}

          }



          例2.

          public ? class ?Temp? {
          ??
          public ? static ? void ?main(String[]?args)? {
          ????Super?sub?
          = ? new ?Sub();
          ????((Sub)sub).plus(
          3 ); // 強制轉換狀態下調用子類方法(不管其有無覆蓋其父類方法)--11
          ????System.out.println(((Sub)sub).i); // 調用變量時的強制轉換,打印結果為11---------------12
          ????((Sub)sub).plus( 2 , 2 ); // -----------------------------------------------------------------------------------13
          ????System.out.println(((Sub)sub).i); // 打印結果為4--------------------------------------------------14
          ????System.out.println(sub.i); // 打印結果為0-----------------------------------------------------------15
          ????sub.print(); // 默認狀態下調用沒有被子類覆蓋的父類方法----------------------------------16
          ????System.out.println(sub.i); // 打印結果為5-----------------------------------------------------------17
          ??}

          }


          class ?Super? {
          ??
          protected ? int ?i = 0 ;
          ??
          void ?plus( int ?i)? {
          ????
          this .i? = 3 ;
          ??}

          ??
          void ?print() {
          ????
          this .i = 5 ;
          ??}

          }


          class ?Sub
          ????
          extends ?Super? {
          ??
          protected ? int ?i? = ? 1 ;
          ??
          void ?plus( int ?i)? {
          ????
          this .i? = ?i? + ? 8 ;
          ??}


          ??
          void ?plus( int ?i,? int ?j)? {
          ????
          this .i? = ?i? + ?j;
          ??}


          ??
          void ?reduce( int ?i)? {
          ????
          this .i? = ? this .i? - ?i;
          ??}

          }

          posted on 2007-01-17 13:14 情天 閱讀(296) 評論(1)  編輯  收藏

          評論:
          # re: 學習和使用繼承時最先要清楚的三點 2007-01-17 13:56 | peace
          老兄,你java幾年了,這么深入  回復  更多評論
            

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


          網站導航:
           
          主站蜘蛛池模板: 舞阳县| 灵川县| 三原县| 鄱阳县| 福贡县| 镇坪县| 柘荣县| 岐山县| 呼伦贝尔市| 麻栗坡县| 富裕县| 江阴市| 弋阳县| 韶山市| 仁寿县| 奉节县| 临潭县| 离岛区| 承德市| 夏河县| 荣昌县| 岳西县| 保定市| 陕西省| 瑞金市| 鄯善县| 富阳市| 化德县| 丰都县| 澳门| 宁安市| 蒲江县| 大洼县| 那坡县| 东乡族自治县| 绵阳市| 工布江达县| 农安县| 合肥市| 大余县| 云霄县|