Java內部類學習筆記,Java類學習筆記

來源:互聯網
上載者:User

Java內部類學習筆記,Java類學習筆記
20160923

  • 定義:將一個類的定義放在另一個類的內部;
  • 從外部類的非靜態方法之外,建立某個內部類的對象:OutClassName.InnerClassName;
  • 內部類擁有所有其外部類的成員的訪問權;
  • 成員內部類不能含有static修飾的變數和方法,因為成員內部類需要先建立了外部類,才能建立它自己的
  • 內部類中產生外部類對象的引用,可以使用OutClassName.this;
 1 public class DoThis { 2     void f(){System.out.println("DoThis.f()");} 3     public class Inner{ 4         public DoThis getOuter(){ 5             return DoThis.this; 6         } 7     } 8     public Inner getInner(){ 9         return new Inner();10     }11     public static void main(String[] args) {12         DoThis dThis = new DoThis();13         DoThis.Inner dThisInner = dThis.getInner();14         dThisInner.getOuter().f();15     }16 }
  • 建立內部類的對象,必須使用外部類對象的引用;
1 public class DoNew {2     public class Inner{};3     public static void main(String[] args) {4         DoNew doNew = new DoNew();5         DoNew.Inner dInner = doNew.new Inner();6     }7 }
  • 建立嵌套類(靜態內部類),不需要外部類對象的引用;
  • private修飾的內部類,只能在其外部類內部訪問;protected修飾的內部類,只有其外部類、其外部類的子類、其外部類同一個包中的其他類可以訪問;
 1 class Parcel4{ 2     private class PContents implements Contents { 3         private int i = 11; 4         @Override 5         public int value() { return i; } 6     } 7     protected class PDestination implements Destination { 8         private String label; 9         private PDestination(String whereTo) { label = whereTo; }10         @Override11         public String readLabel() { return label; }12     }13     public Destination destination(String s){ return new PDestination(s); }14     public Contents contents(){ return new PContents(); }15     Parcel4.PContents t;//PContents是private,只能在Parcel4內部訪問16 }17 public class TestParcel {18     public static void main(String[] args) {19         Parcel4 p = new Parcel4();20         Contents contents = p.contents();21         Destination destination = p.destination("Tasmania");22         //Parcel4.PContents pc = p.new PContents();//PContents是private,只能在Parcel4內部訪問,此處報錯23     }24 }
  • 複雜的內部類:在方法或範圍內定義內部類,理由如下:
  • 舉例

    1、一個定義在方法中的類

 1 public class Parcel5 { 2     public Destination destination(String s){ 3         class PDestination implements Destination{ 4             private String label; 5             private PDestination(String whereTo){ 6                 label = whereTo; 7             } 8             @Override 9             public String readLabel() { return label; }10         }11         return new PDestination(s);12     }13     public static void main(String[] args) {14         Parcel5 p = new Parcel5();15         Destination destination = p.destination("Tasmania");16     }17 }

    2、一個定義在範圍中的類,範圍在方法的內部

 1 public class Parcel6 { 2     private void internalTracking(boolean b) { 3         if (b){ 4             class TrackingSlip { 5                 private String id; 6                 public TrackingSlip(String s) { 7                     id = s; 8                 } 9                 String getSlip(){ return id;}10             }11             TrackingSlip ts = new TrackingSlip("slip");12             String s = ts.getSlip();13         }14         //Can't use it here!Out of scope:15         //TrackingSlip ts = new TrackingSlip("x");16     }17     public void track(){internalTracking(true);}18     public static void main(String[] args) {19         Parcel6 p = new Parcel6();20         p.track();21     }22 }

    3、一個實現了介面的匿名類

    4、一個匿名類,擴充了有非預設構造器的類

    5、一個匿名類,執列欄位初始化

    6、一個匿名類,通過執行個體初始化實現構造(匿名類沒有構造器)

  • 傳遞給匿名內部類的參數,並且在匿名內部類中使用,該參數須定義為final;
  • 匿名內部類可擴充類,也可以實現介面,但不能同時;如果實現介面,只能實現一個介面;
  • 《Java編程思想》199頁,10.6.1再訪Factory 方法,使用匿名內部類的例子,非常好;
  • 嵌套類:static修飾的內部類,無法訪問非靜態外部類對象
  • 嵌套類可以作為介面的一部分,甚至實現外部介面
  •  1 public interface ClassInInterface { 2     void howdy(); 3     class Test implements ClassInInterface{ 4         @Override 5         public void howdy() { System.out.println("Howdy"); } 6         public static void main(String[] args){ 7             new Test().howdy(); 8         } 9     }10 }
  • 內部類能夠多層嵌套,並且能夠透明的訪問所有它嵌入的外部類的成員
  •  1 class A{ 2     private void f(){} 3     class B { 4         private void g(){} 5         public class C { 6             void h() { 7                 g(); 8                 f(); 9             }10         }11     }12 }13 public class MultiNestingAccess {14     public static void main(String[] args) {15         A a = new A();16         A.B ab = a.new B();17         A.B.C abc =ab.new C();18         abc.h();19     }20 }
  • 為什麼需要內部類?
    • 《Java編程思想》204頁解釋為:每個內部類都能獨立的繼承自一個(介面的)實現,所以無論外圍類是否已經繼承了某個(介面的)實現,對於內部類都沒有影響;
    • 簡單講就是,內部類實現介面、繼承某個類,比外部類實現介面少了許多顧慮,外部類實現介面需要考慮全面,在其他地方是否有影響;
    • 內部類可以繼承多個具體類或抽象類別,與介面配合,使“多重繼承”的解決方案變得完美;
    • 內部類可以有多個執行個體,每個執行個體都有自己的狀態資訊,並且與外部類對象相互獨立;
    • 在單個外部類中,可以使多個內部類以不同的方式實現同一個介面,或繼承同一個類;
    • 內部類對象的建立,並不依賴於外部類對象的建立
    • 內部類沒有“is-a”關係,內部類是獨立的實體
  • 閉包,記錄了建立閉包的範圍的一些資訊,使得閉包可調用其外部範圍資料;內部類就是物件導向的閉包;
  • 回調,
  • 通過內部類提供閉包功能舉例:
  •  1 package com.helei.innerclasses; 2 interface Incrementable { 3     void increment(); 4 } 5 class Callee1 implements Incrementable { 6     private int i = 0; 7     @Override 8     public void increment() { 9         i++;10         System.out.println(i);;11     }12 }13 class MyIncrement {14     public void increment() { System.out.println("Other operation");}15     static void f(MyIncrement mi) {mi.increment();}16 }17 class Callee2 extends MyIncrement {18     private int i = 0;19     public void increment() {20         super.increment();21         i++;22         System.out.println(i);23     }24     private class Closure implements Incrementable {25         public void increment() {26             Callee2.this.increment();27         }28     }29     Incrementable getCallbackReference() {30         return new Closure();31     }32 }33 class Caller {34     private Incrementable callbackReference;35     Caller(Incrementable cbh){callbackReference = cbh;}36     void go() {callbackReference.increment();}37 }38 public class Callbacks {39     public static void main(String[] args) {40         Callee1 c1 = new Callee1();41         Callee2 c2 = new Callee2();42         MyIncrement.f(c2);43         Caller caller1 = new Caller(c1);44         Caller caller2 = new Caller(c2.getCallbackReference());45         caller1.go();46         caller1.go();47         caller2.go();48         caller2.go();49     }50 }
  • 看了好幾遍才梳通了以上流程,最好能夠敲一遍,通過debug調試過一遍
  • 內部類與控制架構
  • 內部類的繼承
  • 內部類覆蓋,無效;可以顯式繼承某內部類;
  • 局部內部類,與匿名內部類的區別

 

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.