eric-1001c

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            3 隨筆 :: 45 文章 :: 12 評論 :: 0 Trackbacks

          1) 惰性初始化。就是在正要使用這些對象之前,對對象進行初始化的方法。這種方式可以減少額外的負擔;

           

          public class Bath{
             
          private String
                s1 
          = "Happy",
                s2,
                s3;

             
          public Bath(){
                print(
          "inside Bath()");
                s2 
          = "Joy";
             }


             
          public String toString(){
                
          //惰性初始化
                if(s3==null) s3 = "Exciting";

                
          return "s1="+s1+"; s2="+s2+"; s3="+s3;
             }

          }

          2)在繼承層次結構中,構造器的構建過程(或者說類)是從基類“向外”擴散的,所以基類在導出類構造器可以訪問之前就已經完成了初始化,換句話說,調用基類的構造器必須是導出類構造器中要做的第一件事情(當然這是編譯器的工作); 

          3)代理。是繼承和組合之間的折衷。使用代理可以擁有更多的控制力,因為可以選擇只提供在成員對象中的方法的某個子集(繼承就完全“暴露”了方法接口)

           1class Cleanser {
           2    private String s = "Cleanser";
           3    
           4    public void append(String a ){
           5        s += a;
           6    }

           7    public void dilute(){
           8        append("dilute()");
           9    }

          10    public void apply(){
          11        append("apply()");
          12    }

          13    public void scrub(){
          14        append("scrub()");
          15    }

          16    public String toString(){
          17        return s;
          18    }

          19}

          20
          21public class Detergent {
          22    private String name;
          23    private Cleanser cleanser = new Cleanser();
          24    
          25    public Detergent(String name){
          26        this.name = name;
          27    }

          28        
          29        //只選擇暴露了Cleanser的部分方法子集
          30    public void scrub(){
          31        cleanser.scrub();
          32    }

          33    public void apply(){
          34        cleanser.apply();
          35    }

          36    public void dilute(){
          37        cleanser.dilute();
          38    }

          39    public String toString(){
          40        return cleanser.toString();
          41    }

          42    /**
          43     * @param args
          44     */

          45    public static void main(String[] args) {
          46        Detergent detergent = new Detergent("detergent");
          47        detergent.apply();
          48        detergent.dilute();
          49        System.out.println(detergent.toString());
          50    }

          51}

          3)在清理方法中,必須注意對基類清理方法和成員對象清理方法的調用順序,以防止某個子對象依賴于另一個子對象情形的發生:首先,執行類的所有特定的清理動作,其順序同生成順序相反;然后,調用基類的清理方法

          4)@Override注解可以防止你不想重載(overload)時而意外進行了重載,同時也要求你使用了@Override注解后就得覆蓋原來的方法
           1public class PrivateExtend1{
           2    private final void f(){
           3        System.out.println("privateExtend f()");
           4    }

           5    
           6    private  final void g(){
           7        System.out.println("privateExtend g()");
           8    }

           9}

          10
          11class PrivateExtend2 extends PrivateExtend1{
          12//這里不注解就會錯
          13//    @override 
          14    public final void f(){
          15        System.out.println("privateExtend2 f()");
          16    }

          17    
          18//    @Override
          19    public final void g(){
          20        System.out.println("privateExtend2 g()");
          21    }

          22}

          5) 對于組合和繼承的選擇,一個最清晰的判斷方法就是問一問自己是否需要從新類向基類進行向上轉型。如果必須向上轉型,則繼承是必要的,但如果不需要,則應當好好考慮自己是否需要繼承。組合的好處是允許你在運行時確定對象類型,甚至調用的方法,比如 strategy pattern通過設置基類的成員變量,而傳入導出類作為參數來動態改變對象類型以及方法。

          6) 雖然可以通過protected關鍵創建一些protected域,但最好的方式還是將域保持為private;然后通過protected方法來控制類的繼承者的訪問權限。

          7) 對于基本類型,final使數值恒定不變;而用于對象引用,final使引用恒定不變。一旦引用被初始化指向一個對象,就無法再把它改為指向另一個對象。然而,對象其自身卻是可以被修改的。

          8) final和static final的區別。區別只有當數值運行時內被初始化才會顯現,這是因為編譯器對編譯時數值一視同仁。
          import java.util.Random;

          public class FinalStatic {
              
          private final int i1 = new Random().nextInt();
              
          private static final int i2 =  new Random().nextInt();
              
              
          public String toString(){
                  
          return ("i1: "+i1+"\t"+"i2: "+i2);
              }

              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) {
                  FinalStatic fs 
          = new FinalStatic();
                  System.out.println(fs.toString());
                  
                  FinalStatic fs2 
          = new FinalStatic();
                  System.out.println(fs2.toString());
              }

          }

          //output
          i1: -1658811818    i2: 219593609
          i1: 
          -33942    i2: 219593609

          9) Java允許“空白final”,即指被聲明為final但又未給定初值的域。無論什么情況,編譯器都確??瞻譮inal在使用前必須被初始化
          class Poppet{
              
          private int i;
              Poppet (
          int i){
                  
          this.i = i;
              }

          }

          public class BlankFinal {
              
          //poppet is a blank final
              private final Poppet poppet;
              
              
          //blank final must be initialized before constructor
              public BlankFinal(){
                  poppet
          = new Poppet(5);
              }

              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) {
                  BlankFinal bf 
          = new BlankFinal();
          //        cann't change a final field of the object after the constructor`
          //        bf.poppet = new Poppet(0);
              }

          }

          10)初始化及類的加載:
             1.在Beetle運行時,所發生的第一件事情就是試圖訪問Beetle.maini()(一個static方法)。于是加載器開始啟動并找出Beetle類的編譯代碼(Beetle.class)。在加載過程中,編譯器注意到它有基類(extends告知),于是就繼續加載基類,如果基類還有基類,就繼續加載下去;
             2.接下來,根基類的static初始化即會被執行,然后下一個導出類的static,以此類推。
             3.必要的類都加載完畢,對象開始創建。首先,對象中的所有基本類型都會被設為默認值,對象引用被設為null;然后,基類的成員變量會被初始化;接著基類的構造器會被調用,在基類構造器完成之后,實例變量按其次序被初始化,最后,構造器其余部分被執行
          class Insect{
              
          private int i = 9;
              
          protected int j;
              
              Insect()
          {
                  System.out.println(
          "i="+i+", j="+j);
                  j 
          = 39;
              }

              
              
          private static int x1 = printInit("static Insect.x1 initialized");
              
          static int printInit(String s){
                  System.out.println(s);
                  
          return 47;
              }

          }

          public class Beetle extends Insect{
              
          private int k = printInit("Beetle.k initialized");
              
          public Beetle(){
                  System.out.println(
          "k=" +k);
                  System.out.println(
          "j=" +j);
              }

              
          private static int x2 = printInit("static Beetle.x2 initialized");
              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) {
                  System.out.println(
          "Beetle constructor");
                  Beetle b 
          = new Beetle();
              }

          }

          //output
          static Insect.x1 initialized
          static Beetle.x2 initialized
          Beetle constructor
          i
          =9, j=0
          Beetle.k initialized
          k
          =47
          j
          =39

          posted on 2007-07-10 23:39 Eric-1001c 閱讀(155) 評論(0)  編輯  收藏 所屬分類: ThinkingInJava
          主站蜘蛛池模板: 昭苏县| 娱乐| 虞城县| 定西市| 探索| 宁安市| 淄博市| 梓潼县| 惠东县| 开封县| 郧西县| 乌兰察布市| 和硕县| 博罗县| 东台市| 石河子市| 伽师县| 松溪县| 左云县| 和田县| 木兰县| 青龙| 固安县| 嘉荫县| 河源市| 金堂县| 木兰县| 华安县| 广州市| 囊谦县| 保亭| 迁西县| 商南县| 墨竹工卡县| 阿鲁科尔沁旗| 定南县| 原阳县| 长春市| 汉中市| 南岸区| 沛县|