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

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

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

    posts - 12,  comments - 0,  trackbacks - 0
    合成與繼承
    繼承:
    super關鍵字的使用:super使用在派生類中,如果派生類中重寫了基類的方法,但在這個被重寫的方法中仍然要調用基類的同名的方法,這就要用到super關鍵字,特別是在創建對象時,在帶參數構造函數中調用基類構造函數的情況。
    如:
    class Cleanser {
      private String s = new String("Cleanser");
      public void append(String a) { s += a; }
      public void dilute() { append(" dilute()"); }
      public void apply() { append(" apply()"); }
      public void scrub() { append(" scrub()"); }
      public void print() { System.out.println(s); }
      public static void main(String[] args) {
        Cleanser x = new Cleanser();
        x.dilute(); x.apply(); x.scrub();
        x.print();
      }
    }
    public class Detergent extends Cleanser {
      // Change a method:
      public void scrub() {
        append(" Detergent.scrub()");
        super.scrub(); // Call base-class version
      }
    // Add methods to the interface:
      public void foam() { append(" foam()"); }
      // Test the new class:
      public static void main(String[] args) {
        Detergent x = new Detergent();
        x.dilute();
        x.apply();
        x.scrub();
        x.foam();
        x.print();
        System.out.println("Testing base class:");
        Cleanser.main(args);
      }
    } ///:~
    可以看到基類Cleanser 中定義了scrub方法,但派生類Detergent 中對scrub方法進行了修改,并用在派生類Detergent 的scrub方法中,要調用基本的scrub方法,那么用super.scrub(); 

     基類的初始化:
             當你創建一個派生類的對象的時候,這個對象里面還有一個基類的子對象,這個子對象同基類自己創建的對象沒什么兩樣,只是從外面看來,這個子對象被包裹在派生類的對象里面。
             基類子對象的正確初始化是非常重要的,而且只有一個辦法能保證這一點:調用基類的構造函數來進行初始化,因為只有它才能掌握怎么樣才能正確地進行初始化的信息和權限。java會讓派生類的構造函數自動地調用基類的構造函數。
              示例:
     class Art {
      Art() {
        System.out.println("Art constructor");
      }
    }

    class Drawing extends Art {
      Drawing() {
        System.out.println("Drawing constructor");
      }
    }

    public class Cartoon extends Drawing {
      Cartoon() {
        System.out.println("Cartoon constructor");
      }
      public static void main(String[] args) {
        Cartoon x = new Cartoon();
      }
    } ///:~
    輸出結果為:
    Art constructor
    Drawing constructor
    Cartoon constructor
    一看結果便一目了然了。

    上面的示例是不帶任何參數的情況,如果構造函數中帶有參數的話,那這里又要用到super的特性了。與上面super的使用涵意一樣,super在這里用作:派生的帶參數構造函數中調用基類的帶參構造函數,只是這里不象上面那樣super.scrub();這里只使用super(i);即可。
            
    class Game {
      Game(int i) {
        System.out.println("Game constructor");
      }
    }

    class BoardGame extends Game {
      BoardGame(int i) {
        super(i);
        System.out.println("BoardGame constructor");
      }
    }

    public class Chess extends BoardGame {
      Chess() {
        super(11);
        System.out.println("Chess constructor");
      }
      public static void main(String[] args) {
        Chess x = new Chess();
      }
    } ///:~
    輸出結果是:
    Game constructor
    BoardGame constructor
    Chess constructor

    合成和繼承一起使用,實現類的復用:

    class Plate {
      Plate(int i) {
        System.out.println("Plate constructor");
      }
    }

    class DinnerPlate extends Plate {
      DinnerPlate(int i) {
        super(i);
        System.out.println(
          "DinnerPlate constructor");
      }
    }

    class Utensil {
      Utensil(int i) {
        System.out.println("Utensil constructor");
      }
    }

    class Spoon extends Utensil {
      Spoon(int i) {
        super(i);
        System.out.println("Spoon constructor");
      }
    }

    class Fork extends Utensil {
      Fork(int i) {
        super(i);
        System.out.println("Fork constructor");
      }
    }

    class Knife extends Utensil {
      Knife(int i) {
        super(i);
        System.out.println("Knife constructor");
      }
    }

    // A cultural way of doing something:
    class Custom {
      Custom(int i) {
        System.out.println("Custom constructor");
      }
    }

    public class PlaceSetting extends Custom {
      Spoon sp;
      Fork frk;
      Knife kn;
      DinnerPlate pl;
      PlaceSetting(int i) {//把初始化工作都放在構造函數中
        super(i + 1);
        sp = new Spoon(i + 2);
        frk = new Fork(i + 3);
        kn = new Knife(i + 4);
        pl = new DinnerPlate(i + 5);
        System.out.println(
          "PlaceSetting constructor");
      }
      public static void main(String[] args) {
        PlaceSetting x = new PlaceSetting(9);
      }
    } ///:~
            盡管編譯器會強迫我們對基礎類進行初始化,并要求我們在構建器最開頭做這一工作,但它并不會監視我們是否正確初始化了成員對象。所以對此必須特別加以留意。
    FINAL關鍵字:
            FINAL關鍵字指“那樣東西是不允許改動”,你可能會出于兩點考慮不想讓別人作改動:設計和效率。由于這兩個原因差別很大,所以很可能會誤用final關鍵字。
    final的三種用途:數據(Data)、方法(method)、類(class)。
     很多語言通知編譯器:“這段常量(constant)數據”的手段。常量能用下列兩種情況出現:
            1、可以是“編譯時的常量”,這樣以后就不能改了;
            2、也可以是運行時初始化的值,這個值以后就不想再改了。
            如果是編譯時的常量,編譯器會把常量放到算式里面;這樣編譯的時候就能進行計算,因此也就降低了運行時的開銷。在Java 中這種常量必須是primitive 型的,而且要用final 關鍵詞表示。這種常量的賦值必須在定義的時候進行。
            一個既是static 又是final 的數據成員會只占據一段內存,并且不可修改。
            當final 不是指primitive,而是用于對象的reference 的時候,意思就有點不一樣了。對primitive 來說,final 會將這個值定義成常量,但是對于對象的reference 而言,final 的意思則是這個reference 是常量。初始化的時候,一旦將reference 連到了某個對象,那么它就再也不能指別的對象了。但是這個對象本身是可以修改的;Java 沒有提供將某個對象作成常量的方法。
            (但是你可以自己寫一個類,這樣就能把類當做常量了)
            這種局限性也體現在數組上,因為它也是一個對象。
    注意,通常約定,被初始化為常量值的final static 的primitive 的名字全都用大寫,詞與詞之間用下
    劃線分開,如VAL_ONE
    Final 方法
    使用final 方法的目的有二:
            第一,為方法上“鎖”,禁止派生類進行修改。這是出于設計考慮。當你希望某個方法的功能,能在繼承過程中被保留下來,并且不被覆寫,就可以使用這個方法。
            第二個原因就是效率。如果方法是final 的,那么編譯器就會把調用轉換成“內聯的(inline)”。它會用方法本身的拷貝來代替方法的調用
    final 和private
            private 方法都隱含有final 的意思。由于你不能訪問private 的方法,因此你也不能覆寫它。你可以給private 方法加一個final 修飾符,但是這樣做什么意義也沒有。
            這個問題有可能會造成混亂,因為即使你覆寫了一個private 方法(它隱含有final 的意思),看上去它還是可以運行的,而且編譯器也不會報錯:
            class WithFinals {
                // Identical to "private" alone:
                private final void f() {
                        System.out.println("WithFinals.f()");
                                              }
                / / Also automatically "final":
               private void g() {
                        System.out.println("WithFinals.g()");
                                     }
            }
            class OverridingPrivate extends WithFinals {
                    private final void f() {
                            System.out.println("OverridingPrivate.f()");
                                                      }
                    private void g() {
                            System.out.println("OverridingPrivate.g()");
                                                      }
             }
    只有是基類接口里的東西才能被“覆寫”,如果方法是private 的,那它就不屬于基類的接口。它只能算是被類隱藏起來的,正好有著相同的名字的代碼。如果你在派生類里創建了同名的public 或protected,或package 權限的方法,那么它們同基類中可能同名的方法,沒有任何聯系。你并沒有覆寫那個方法,你只是創建了一個新的方法。由于private 方法是無法訪問的,實際上是看不見的,因此這么作除了會影響類的代碼結構,其它什么意義都沒有。
    Final 類
    把整個類都定義成final 的(把final 關鍵詞放到類的定義部分的前面)就等于在宣布,你不會去繼承這個類,你也不允許別人去繼承這個類。換言之,出于類的設計考慮,它再也不需要作修改了,或者從安全角度出發,你不希望它再生出子類。
    final class Dinosaur{}
    注意,final 類的數據可以是final 的,也可以不是final 的,這要由你來決定。無論類是不是final 的,這一條都適用于“將final 用于數據的”場合。但是,由于final 類禁止了繼承,覆寫方法已經不可能了,因
    此所有的方法都隱含地變成final 了。你可以為final 類的方法加一個final 修飾符,但是這一樣沒什么意義。
    posted on 2007-12-20 17:33 仰望者 閱讀(238) 評論(0)  編輯  收藏

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


    網站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 亚洲av无码一区二区乱子伦as| 日本亚洲视频在线 | 精品无码专区亚洲| 国产精品入口麻豆免费观看| 久久久婷婷五月亚洲97号色| 无码人妻精品中文字幕免费| 久久夜色精品国产嚕嚕亚洲av| 久久免费高清视频| a级毛片免费网站| 久久久久亚洲精品天堂久久久久久| 久久久亚洲裙底偷窥综合| 99re6在线精品视频免费播放 | 国产1000部成人免费视频| 亚洲人成黄网在线观看| 女人18毛片水真多免费看| 亚洲国产美女精品久久久| 国产乱子伦精品免费女| 四虎精品成人免费视频| 国产成人亚洲精品青草天美| 人妻丰满熟妇无码区免费| 日本亚洲免费无线码| 四虎免费影院4hu永久免费| 中文字幕免费播放| 亚洲熟妇av一区| 国产免费无遮挡精品视频| 好吊色永久免费视频大全| 亚洲无成人网77777| 免费a级毛片永久免费| a国产成人免费视频| 久久精品亚洲AV久久久无码 | 麻豆69堂免费视频| 亚洲av无码乱码国产精品fc2| 精品福利一区二区三区免费视频| 亚洲国产精品无码久久久蜜芽 | 日韩毛片免费一二三| 久久久亚洲精品视频| 好男人视频在线观看免费看片| 日韩在线观看视频免费| 亚洲电影免费观看| 久久久久国产亚洲AV麻豆| 国产无人区码卡二卡三卡免费 |