eric-1001c

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

           

          class Egg{
              
          private Yolk y;
              
          protected class Yolk{
                  
          public Yolk(){
                      System.out.println(
          "Egg.Yolk()");
                  }

              }

              
          public Egg(){
                  System.out.println(
          "new Egg()");
                  y 
          = new Yolk();
              }

          }

          //bigegg extend egg, and try "override" the yolk
          public class BigEgg extends Egg{
              
          public class Yolk{
                  
          public Yolk(){
                      System.out.println(
          "BigEgg.Ylok()");    
                  }

              }

              
          public static void main(String[] args) {
                  
          new BigEgg();
              }

          }

          內(nèi)部類是一種非常有用的機制,它允許你把一些邏輯相關(guān)的類組織在一起,并控制位于內(nèi)部類的可視性(進入修飾符和其它普通類元素沒有區(qū)別)。同時內(nèi)部類能夠與外部類通信。利用內(nèi)部類的特性可以使得寫出的代碼優(yōu)雅而清雅。

          1)內(nèi)部類可以在內(nèi)部進行使用,更典型的情況是在外部類設(shè)置一個方法返回一個指向內(nèi)部類的引用
          2)如果想從外部類的非靜態(tài)方法之外的任意位置創(chuàng)建某個內(nèi)部類的對象(這個內(nèi)部類必須是public),必須具體指明這個對象的類型:OuterClassName.InnerClassName;在new表達式中提供對其它外部類對象的引用,需要使用.new語法。


          OutClass oc 
          = new OutClass();
          OutClass.InnerClass ocic 
          = oc.new InnerClass();

          這個例子也告訴我們,必須使用外部類的對象來創(chuàng)建內(nèi)部類對象,不能直接創(chuàng)建內(nèi)部類對象,因為它們之前必須建立一個聯(lián)系(當然除了嵌套類--靜態(tài)內(nèi)部類)

          3)內(nèi)部類和制造它的外圍對象之間有一種聯(lián)系(對象創(chuàng)建一個內(nèi)部類對象時,內(nèi)部類對象會捕獲一個指向那個外圍類對象的引用),這種聯(lián)系使得它能訪問外圍對象的所有成員,而不要任何特殊條件。此外,內(nèi)部類還擁有其外圍類的所有元素的訪問權(quán)。(是不是可以把內(nèi)部類看成外部類的一個元素,一個“特殊”的“類元素”)
          如果需要生成對外部類對象的引用,可以使用外部類的名字后面緊跟圓點和this“.this”:

          public class Outer{

             
          public class Inner{
             
                
          public Outer getOuter(){
                   
          return Outer.this;
                }


          }

          4) 當將內(nèi)部類向上轉(zhuǎn)型為其基類,尤其是轉(zhuǎn)型為一個接口的時候,內(nèi)部類就有了用武之地。這是因為內(nèi)部類--某個接口的實現(xiàn)--能夠完全不可見,并且不可用(將內(nèi)部類進入修飾符設(shè)置為private或protected就可以了)。所得到的只是指向基類或接口的引用,所以能夠很方便地隱藏實現(xiàn)細節(jié),也完全阻止任何依賴于類型的編碼
          package chapter10;

          interface Destination{
              String readLabel();
          }

          interface Contents{
              
          int value();
          }

          class OuterInner{
              
          //inner class1
              private class PDestination implements Destination{
                  
          private String label;
                  
          private PDestination (String whereto){
                      label 
          = whereto;
                  }

                  
          public String readLabel() {
                      
          return label;
                  }

              }
          ;
              
          //inner class2
              protected class PContents implements Contents{
                  
          private int i = 11;
                  
          public int value() {
                      
          return i;
                  }

              }
          ;
              
              
          //method to ge the reference of the inner class pdestination and pcontent
          //    notice that we return a interface instead of the implements of the interface
              public Destination getDestination(String s){
                  
          return new PDestination(s);
              }

              
          public Contents getContents(){
                  
          return new PContents();
              }

          }


          public class InnerUpcast {

              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) {
                  OuterInner oi 
          = new OuterInner();
          //        we also use the interface as the type of the class instead of the inner class type
                  Contents c =oi.getContents();
                  Destination d 
          = oi.getDestination("Hello");
              }


          5) 同樣的我們可以在任意一個方法中或作用域內(nèi)創(chuàng)建一個內(nèi)部類,除了要注意它(內(nèi)部類)的使用作用域外,其它用法和在類的內(nèi)部類用法無異。
          6)匿名內(nèi)部類:沒有名字的,不能有構(gòu)造器的類
          interface Contents{
              
          int value();
          }

          abstract class Base{
              
          public abstract void f();
          }

          //use anonymous inner class as the vaule of return
          //play your attendtion on that the value of return not only is a inner class
          //but also it will be casted up as a interface, that's the amazing place
          class OuterInner{
          //  use interface as anonymous inner class
              public Contents getContents(){
                  
          return new Contents(){
                      
          private int i = 11;
                      
          public int value() {
                          
          return i;
                      }

                  }
          ;
              }

          //    use abstract class as anonymous inner class
              public Base getBase(){
                  
          return new Base(){
                      
          public void f(){
                          
          //do something here
                      }

                  }
          ;
              }

          }


          public class AnonymousInner {
              
          public static void main(String[] args) {
                  OuterInner oi 
          = new OuterInner();
                  Contents c 
          =oi.getContents();
                  Base b 
          = oi.getBase();
              }

          }
          匿名內(nèi)部類既可以擴展類(抽象類),也可以實現(xiàn)接口,但不能兩者兼?zhèn)洹H绻涿麅?nèi)部類要使用在其外部定義的對象,則要求該參數(shù)引用為final

          7)要創(chuàng)建嵌套類(靜態(tài)內(nèi)部類)意味著:并不需要其外圍類的對象;不能從嵌套類的對象中訪問非靜態(tài)的外圍類對象。嵌套類與普通內(nèi)部類還有一個區(qū)別:普通內(nèi)部類的字段與方法只能放在類的外部層次上,所以普通的內(nèi)部類不能有static數(shù)據(jù)和static字段,也不能包含嵌套類。但是嵌套類可以包含所有這些東西。
          8)一個內(nèi)部類被嵌套多少層并不重要,它能透明地訪問所有它所嵌入的外圍類的所有成員
          9)“每個內(nèi)部類都能獨立地繼承自一個(接口的)實現(xiàn),所以無論外圍類是否已經(jīng)繼承了某個(接口的)實現(xiàn),對于內(nèi)部類都沒有影響”,這樣的內(nèi)部類特性使得其很多解決“多重繼承”:
                 a. 內(nèi)部類可以有多個實例,每個實例都有自己的狀態(tài)信息,并且與其外圍類對象的信息相互獨立(通過匿名內(nèi)部類實現(xiàn))
                 b. 在單個外圍類中,可以讓多個內(nèi)部類以不同的方式實現(xiàn)同一個接口,或繼承同一個類(通過匿名內(nèi)部類實現(xiàn))
                 c. 創(chuàng)建內(nèi)部類對象的時候并不依賴于外圍類對象的創(chuàng)建,并沒有令人迷惑的“is-a”關(guān)系,它就是一個獨立的實體

          class PetSequence{
              String[] str 
          =new String[]{"Rat","Manx","Cymric","Mutt","Pug"};
              
          protected ArrayList<String> pets = new ArrayList<String>(
                      Arrays.asList(str));
          }


          public class NonClollectionSequence extends PetSequence{
          //    我們在這創(chuàng)建了3個方法,返回類型都是Iterable接口。但不同方法對Iterable接口的實現(xiàn)是不同的
          //    使用匿名內(nèi)部類很好的以不同的方式實現(xiàn)同一個接口,而且并不依賴于外圍對象
              public Iterable<String> Iterator(){
                  
          return new Iterable<String>(){
                      
          public Iterator<String> iterator(){
                          
          return new Iterator<String>(){
                              
          private int index = 0;
                              
          public boolean hasNext(){
                                  
          return index< pets.size();
                              }

                              
          public String next(){return pets.get(index++);}
                              
          public void remove(){
                                  
          throw new UnsupportedOperationException();
                              }

                          }
          ;
                      }

                  }
          ;
              }

              
              
          public Iterable<String> reversed(){
                  
          return new Iterable<String>(){
                      
          public Iterator<String> iterator(){
                          
          return new Iterator<String>(){
                              
          private int index = pets.size()-1;
                              
          public boolean hasNext(){
                                  
          return index< pets.size();
                              }

                              
          public String next(){
                                  
          return pets.get(index--);
                              }

                              
          public void remove(){
                                  
          throw new UnsupportedOperationException();
                              }

                          }
          ;
                      }

                  }
          ;
              }

              
              
          public Iterable<String> randomized(){
                  
          return new Iterable<String>(){
                      
          public Iterator<String> iterator(){
                          List
          <String> shuffed = new ArrayList<String>(Arrays.asList(str));
                          Collections.shuffle(shuffed, 
          new Random(47));
                          
          return shuffed.iterator();
                      }

                  }
          ;
              }


              
          public static void main(String[] args) {
                  NonClollectionSequence s 
          = new NonClollectionSequence();
                  
          for(String string: s.reversed())
                      System.out.println(string);
                  System.out.println();
                  
          for(String string2: s.randomized())
                      System.out.println(string2);
              }

          }

          10)如果創(chuàng)建一個繼承具有內(nèi)部類的外圍類的新類,并在新類中試圖覆蓋內(nèi)部類,會發(fā)生什么呢?

          當繼承了某個外圍類的時候,內(nèi)部類并沒有發(fā)生什么特別的神奇的變化。這兩個內(nèi)部類是完全獨立的兩個實體,各自在自己的命名空間內(nèi)
          11)內(nèi)部類的標識符:外圍類的名字,加上‘$’,再加上內(nèi)部類的名字,比如OuterClass$InnerClass;對了匿名內(nèi)部類,編譯器會簡單地產(chǎn)生一個數(shù)字作為其標識符,比如OuterClass$1
          12)局部內(nèi)部類VS匿名內(nèi)部類
                a. 局部內(nèi)部類可以提供一個構(gòu)造器,方便重載構(gòu)造器,而匿名內(nèi)部類只能用于實例初始化
                b. 局部內(nèi)部類可以被使用多次,然而匿名內(nèi)部類只能實例化一次
          posted on 2007-07-17 11:18 Eric-1001c 閱讀(224) 評論(0)  編輯  收藏 所屬分類: ThinkingInJava
          主站蜘蛛池模板: 连江县| 卢龙县| 禄劝| 金塔县| 得荣县| 大安市| 吉木萨尔县| 鄄城县| 红河县| 普兰县| 汉中市| 邓州市| 湘乡市| 贵港市| 拜泉县| 牙克石市| 宁阳县| 法库县| 屏山县| 黎城县| 弥勒县| 柳林县| 红原县| 布尔津县| 屏山县| 专栏| 来安县| 阿坝县| 澄江县| 灵石县| 吕梁市| 池州市| 左贡县| 西安市| 达拉特旗| 朝阳市| 元朗区| 青河县| 兰州市| 新龙县| 鄢陵县|