ChenGen

          一切歸零,重新開始
          隨筆 - 13, 文章 - 10, 評論 - 21, 引用 - 0
          數(shù)據(jù)加載中……

          JAVA類繼承過程中其成員的一些問題

          JAVA類繼承過程中其成員的一些問題
          ???
          一、構造函數(shù)的問題:

          ???構造函數(shù)不能繼承。子類的構造函數(shù)可以通過super關鍵字顯式調用父類中的構造函數(shù)。如果子類中的構造函數(shù)沒有顯式調用父類中的構造函數(shù),編譯器就會自動在子類的構造函數(shù)中調用父類中參數(shù)為空的構造函數(shù)。于是,當父類中沒有參數(shù)為空的構造函數(shù),而子類中又沒有顯示調用父類的其他構造函數(shù),編譯時就會報錯。這一點需要特別注意。當父類中沒有定義任何構造函數(shù)時,編譯器就會為它指定一個參數(shù)為空的默認的構造函數(shù);如果父類中定義了構造函數(shù),那么編譯器就不會為它指定一個參數(shù)為空的默認構造函數(shù)了。因此,如果某個類有可能成為其他類的父類,為了避免發(fā)生不必要的編譯錯誤,最好為它編寫一個參數(shù)為空的構造函數(shù)。

          eg1.父類Sup中沒有定義構造函數(shù),編譯程序將為它指定一個參數(shù)為空的默認構造函數(shù)。子類Sub中也沒有定義構造函數(shù),編譯程序也會為它指定一個參數(shù)為空的默認的構造函數(shù),并且會在這個默認的構造函數(shù)中調用父類的參數(shù)為空的構造函數(shù)。
          public?class?Sub??extends?Sup{
          ????
          //子類中沒有定義構造函數(shù)
          ????public?static?void?main(String?args[]){
          ????????Sub?sub
          =new?Sub();
          ????}

          }


          class?Sup{
          ????
          //父類中沒有定義構造函數(shù)
          }


          eg2.父類Sup中沒有定義構造函數(shù),編譯程序將為它指定一個參數(shù)為空的默認構造函數(shù)。子類定義了一個帶整型參數(shù)的構造函數(shù),在這個構造函數(shù)中子類沒有顯式調用父類的構造函數(shù),所以編譯器為在它里面調用父類中參數(shù)為空的構造函數(shù)。

          public?class?Sub??extends?Sup{
          ????
          //子類中定義類一個帶整型變量參數(shù)的構造函數(shù)
          ????public?Sub(int?i){
          ????????
          //
          ????}

          ????
          public?static?void?main(String?args[]){
          ????????Sub?sub
          =new?Sub(1);
          ????}

          }

          class?Sup{
          ????
          //父類中沒有定義構造函數(shù)
          }

          eg3.父類中定義了一個帶整型參數(shù)的構造函數(shù),因此編譯器不再為它指定參數(shù)為空的默認的構造函數(shù)。子類中也定義了一個帶整型參數(shù)的構造函數(shù)。編譯時,編譯器將試圖在子類的構造函數(shù)中調用父類的參數(shù)為空的構造函數(shù),但是父類中沒有定義參數(shù)為空的構造函數(shù),所以編譯程序將會報錯。排錯的方法時在子類的構造函數(shù)中顯示調用父類的構造函數(shù),或者在父類中添加一個帶空參數(shù)的構造函數(shù)。

          public?class?Sub??extends?Sup{
          ????
          //子類中定義類一個帶整型變量參數(shù)的構造函數(shù)
          ????public?Sub(int?i){
          ????????
          //
          ????}

          ????
          public?static?void?main(String?args[]){
          ????????Sub?sub
          =new?Sub(1);
          ????}

          }


          class?Sup{
          ????
          //父類中定義了一個帶整型參數(shù)的構造函數(shù)
          ????public?Sup(int?i){
          ????????
          //
          ????}

          }

          ???排錯方法1:

          public?class?Sub??extends?Sup{
          ????
          //子類中定義類一個帶整型變量參數(shù)的構造函數(shù)
          ????public?Sub(int?i){
          ????????
          super(i);//調用父類中的構造函數(shù)
          ????}

          ????
          public?static?void?main(String?args[]){
          ????????Sub?sub
          =new?Sub(1);
          ????}

          }


          class?Sup{
          ????
          //父類中定義了一個帶整型參數(shù)的構造函數(shù)
          ????public?Sup(int?i){
          ????????
          //
          ????}

          }

          ???排錯方法2:

          public?class?Sub??extends?Sup{
          ????
          //子類中定義類一個帶整型變量參數(shù)的構造函數(shù)
          ????public?Sub(int?i){
          ????????
          //
          ????}

          ????
          public?static?void?main(String?args[]){
          ????????Sub?sub
          =new?Sub(1);
          ????}

          }


          class?Sup{
          ????
          //父類中定義了一個帶整型參數(shù)的構造函數(shù)
          ????public?Sup(int?i){
          ????????
          //
          ????}

          ????
          //定義一個帶空參數(shù)的構造函數(shù)
          ????public?Sup(){
          ????????
          //
          ????}

          }


          二、類方法和實例方法在繼承過程中的問題:
          ???
          ???首相要明確一個概念,JAVA中通過什么來區(qū)別不同的成員——答案是標記。所謂標記,對于方法而言是指方法的名字、參數(shù)的數(shù)量和參數(shù)的類型;對于變量而言是指變量的名稱。注意,標記不包括方法的返回值和變量的類型。

          ???如果子類的實例方法和父類的實例方法具有相同的標記,子類的方法將覆蓋父類的方法。但是如果子類的方法和父類的方法具有相同的標記,但是具有不同的返回值類型,編譯程序將會報錯。排錯的方法是修改子類中這個方法的返回值類型,使它父類中相同標記的方法的返回值一樣。

          public?class?Sub??extends?Sup{
          ????
          //子類中的這個方法父類中的方法有相同的標記,
          ????
          //但返回值不同,編譯程序就會報錯
          ????int?test(){
          ????????
          return??1;
          ????}

          }


          class?Sup{
          ????
          void?test(){
          ????????
          //
          ????}

          }

          ???排錯:

          public?class?Sub??extends?Sup{
          ????
          //子類中的方法正確覆蓋了父類中的方法
          ????void?test(){
          ????????
          //
          ????}

          }


          class?Sup{
          ????
          void?test(){
          ????????
          //
          ????}

          }

          ???同樣如果子類的類方法和父類的類方法具有相同的標記,那么子類的類方法將隱藏父類的類方法。注意這里不叫覆蓋,而叫隱藏,兩者的區(qū)別將在后面討論。同樣,如果子類的類方法和父類的類方法具有相同的標記和不同的返回值,編譯程序也會報錯。解決的問題的方法同實例方法一樣。

          ???但是實例方法不能覆蓋類方法,類方法也不能隱藏實例方法,否則編譯程序就會報錯。
          ???
          ???實例方法不能覆蓋類方法(編譯時報錯):
          public?class?Sub??extends?Sup{
          ????
          //實例方法不能覆蓋類方法,編譯時報錯
          ????void?test(){
          ????????
          //
          ????}

          }


          class?Sup{
          ????
          static?void?test(){
          ????????
          //
          ????}

          }

          ???類方法不能隱藏實例方法(編譯時報錯):
          public?class?Sub??extends?Sup{
          ????
          //類方法不能隱藏實例方法,編譯時報錯
          ????static?void?test(){
          ????????
          //
          ????}

          }


          class?Sup{
          ?????
          void?test(){
          ????????
          //
          ????}

          }

          ???覆蓋和隱藏的區(qū)別。對于隱藏的方法,運行時系統(tǒng)調用當前對象引用的編譯時類型中定義的方法;對于覆蓋的方法,運行時系統(tǒng)調用當前對象引用運行時類型中定義的方法。一個是調用編譯時類型中定義的方法,一個是調用運行時類型中定義的方法。通過下面這個例子可以直觀的看出兩者之間的差別。

          class?Planet?{
          ????
          public?static?void?hide()?{
          ????????System.out.println(
          "The?hide?method?in?Planet.");
          ????}


          ????
          public?void?override()?{
          ????????System.out.println(
          "The?override?method?in?Planet.");
          ????}

          }


          class?Earth?extends?Planet?{
          ????
          public?static?void?hide()?{
          ????????System.out.println(
          "The?hide?method?in?Earth.");
          ????}


          ????
          public?void?override()?{
          ????????System.out.println(
          "The?override?method?in?Earth.");
          ????}


          ????
          public?static?void?main(String?args[])?{
          ????????Earth?earth?
          =?new?Earth();
          ????????Planet?planet?
          =?(Planet)?earth;
          ????????planet.hide();?//?result:"The?hide?method?in?Planet."
          ????????planet.override();?//?result:"The?override?method?in?Earth."
          ????}

          }

          ???Earth類覆蓋了Planet類的override方法,并隱藏了它的hide方法。在main方法中創(chuàng)建了一個Earth的實例,并將此實例轉換為一個Planet的引用。然后通過Planet引用調用override方法和hide方法。hide方法是類方法,因此根據(jù)引用的類來決定調用哪個方法,所以planet.hide()調用的是Planet的類方法hide。override方法是實例方法,因此調用的是運行時的實例中的方法,因為planet引用的是Earth的實例,因此planet.override()調用的是Earth類中實例方法override。

          ???JAVA正是通過實例方法的這種覆蓋關系來實現(xiàn)多態(tài)的目的。

          三、類的變量在繼承過程中的問題:
          ???
          ???如果子類中的變量如果和父類中的變量具有相同的標記——即相同的名字——那么子類中的變量一就會隱藏父類中的變量。不過他們的類型是什么,也不管他們是類變量還是實例變量。只要他們具有相同的名字。

          public?class?Sub?extends?Sup?{
          ????
          float?i;?//子類中的實例變量隱藏父類中的類變量,并且具有不同的類型
          ????float?j;?//子類中的類變量隱藏父類中的實例變量,并且具有不同的類型
          ????int?k;?//子類中的實例變量隱藏父類中的實例變量
          ????static?int?l;?//子類中的類變量隱藏父類中的類變量
          }


          class?Sup?{
          ????
          static?int?i?;
          ????
          int?j;
          ????
          int?k;
          ????
          static?int?l;
          }

          ???同子類中的類方法隱藏父類中的類方法一樣,當子類中的變量覆蓋父類中的變量的時候,到底使用哪個變量,要根據(jù)引用的類型來確定。

          ???下面是一個類成員繼承關系的綜合例子:
          package?basic;

          public?class?Subclass?extends?Superclass?{
          ????
          static?String?staticString?=?"static?String?in?Subclass";

          ????String?instanceString?
          =?"instance?String?in?Subclass";

          ????
          static?void?staticPrintf(float?a)?{
          ????????System.out.println(
          "static?printf?method?in?Subclass");
          ????}


          ????
          void?instancePrintf(float?a)?{
          ????????System.out.println(
          "instance?printf?method?in?Subclass");
          ????}

          ????

          ????
          public?static?void?main(String?args[])?{
          ????????Subclass?sub?
          =?new?Subclass();
          ????????Superclass?sup?
          =?(Superclass)?sub;
          ????????System.out.println(sub.staticString);?
          //?static?String?in?Subclass
          ????????System.out.println(sub.instanceString);?//?instance?String?in?Subclass
          ????????System.out.println(sup.staticString);?//?static?String?in?Superclass
          ????????System.out.println(sup.instanceString);?//?instance?String?in?Superclass

          ????????sub.staticPrintf(
          1);?//?static?printf?method?in?Subclass
          ????????sub.instancePrintf(1);?//?instance?printf?method?in?Subclass
          ????????sup.staticPrintf(1);?//?static?printf?method?in?Superclass
          ????????sup.instancePrintf(1);?//?instance?printf?method?in?Subclass
          ????}

          }


          class?Superclass?{
          ????
          static?String?staticString?=?"static?String?in?Superclass";

          ????String?instanceString?
          =?"instance?String?in?Superclass";

          ????
          static?void?staticPrintf(float?a)?{
          ????????System.out.println(
          "static?printf?method?in?Superclass");
          ????}


          ????
          void?instancePrintf(float?a)?{
          ????????System.out.println(
          "instance?printf?method?in?Subclass");
          ????}

          ????
          }

          posted on 2006-09-29 13:41 ChenGen 閱讀(2739) 評論(1)  編輯  收藏

          評論

          # re: JAVA類繼承過程中其成員的一些問題  回復  更多評論   

          恩~

          特別是后面的細節(jié)問題~ 還真的沒仔細研究過!

          好啊!! 支持!!
          2006-10-03 20:05 | fantasy

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


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 鸡泽县| 获嘉县| 巨鹿县| 涞水县| 临朐县| 义马市| 吴桥县| 昌平区| 延安市| 新巴尔虎左旗| 剑河县| 永定县| 诸暨市| 巨鹿县| 定安县| 芜湖市| 宾川县| 宁海县| 中方县| 邯郸县| 郸城县| 商城县| 乐亭县| 北宁市| 枣阳市| 噶尔县| 察隅县| 苗栗市| 松原市| 美姑县| 镇巴县| 西乌| 达日县| 镇安县| 江达县| 乐昌市| 海口市| 全南县| 克什克腾旗| 萨嘎县| 桐乡市|