天天看點

Java靜态内部類、匿名内部類、成員式内部類和局部内部類

内部類可以是靜态(static)的,可以使用 public、protected 和 private 通路控制符,而外部類隻能使用 public,或者預設。

成員式内部類

在外部類内部直接定義(不在方法内部或代碼塊内部)的類就是成員式内部類,它可以直接使用外部類的所有變量和方法,即使是 private 的。外部類要想通路内部類的成員變量和方法,則需要通過内部類的對象來擷取。

1 public class Outer{
 2     private int size;
 3     public class Inner {
 4         public void dostuff() {
 5             size++;
 6         }
 7     }
 8     public void testTheInner() {
 9         Inner in = new Inner();
10         in.dostuff();
11     }
12 }      

成員式内部類如同外部類的一個普通成員。

成員式内部類可以使用各種修飾符,包括 public、protected、private、static、final 和 abstract,也可以不寫。

若有 static 修飾符,就為類級,否則為對象級。類級可以通過外部類直接通路,對象級需要先生成外部的對象後才能通路。

非靜态内部類中不能聲明任何 static 成員。

内部類可以互相調用,例如:

1 class A {
2     // B、C 間可以互相調用
3     class B {}
4     class C {}
5 }      

成員式内部類的通路

内部類的對象以成員變量的方式記錄其所依賴的外層類對象的引用,因而可以找到該外層類對象并通路其成員。該成員變量是系統自動為非 static 的内部類添加的,名稱約定為“outClassName.this”。

  1. 使用内部類中定義的非靜态變量和方法時,要先建立外部類的對象,再由“outObjectName.new”操作符建立内部類的對象,再調用内部類的方法,如下所示:
1 public class Demo{
 2     public static void main(String[] args) {
 3         Outer outer = new Outer();
 4         Outer.Inner inner = outer.new Inner();
 5         inner.dostuff();
 6     }
 7 }
 8 class Outer{
 9     private int size;
10     class Inner{
11         public void dostuff() {
12             size++;
13         }
14     }
15 }      
  1. static 内部類相當于其外部類的 static 成員,它的對象與外部類對象間不存在依賴關系,是以可直接建立。示例如下:
1 public class Demo{
 2     public static void main(String[] args) {
 3         Outer.Inner inner = new Outer.Inner();
 4         inner.dostuff();
 5     }
 6 }
 7 
 8 class Outer{
 9     private static int size;
10     static class Inner {
11         public void dostuff() {
12             size++;
13             System.out.println("size=" + size);
14         }
15     }
16 }      
  1.  運作結果:
  1. 由于内部類可以直接通路其外部類的成分,是以當内部類與其外部類中存在同名屬性或方法時,也将導緻命名沖突。是以在多層調用時要指明,如下所示:
1 public class Outer{
 2     private int size;
 3     public class Inner{
 4         private int size;
 5         public void dostuff(int size){
 6             size++;  // 局部變量 size;
 7             this.size;  // 内部類的 size
 8             Outer.this.size++;  // 外部類的 size
 9         }
10     }
11 }      
  1. 局部内部類

    局部内部類(Local class)是定義在代碼塊中的類。它們隻在定義它們的代碼塊中是可見的。

    局部類有幾個重要特性:

    僅在定義了它們的代碼塊中是可見的;

    可以使用定義它們的代碼塊中的任何局部 final 變量;

    局部類不可以是 static 的,裡邊也不能定義 static 成員;

    局部類不可以用 public、private、protected 修飾,隻能使用預設的;

    局部類可以是 abstract 的。

    請看下面的代碼:

1 public class Outer {
 2     public static final int TOTAL_NUMBER = 5;
 3     public int id = 123;
 4     public void func() {
 5         final int age = 15;
 6         String str = "http://www.weixueyuan.net";
 7         class Inner {
 8             public void innerTest() {
 9                 System.out.println(TOTAL_NUMBER);
10                 System.out.println(id);
11                 // System.out.println(str);不合法,隻能通路本地方法的final變量
12                 System.out.println(age);
13             }
14         }
15         new Inner().innerTest();
16     }
17     public static void main(String[] args) {
18         Outer outer = new Outer();
19         outer.func();
20     }
21 }      
  1. 運作結果:
    Java靜态内部類、匿名内部類、成員式内部類和局部内部類

    匿名内部類

    匿名内部類是局部内部類的一種特殊形式,也就是沒有變量名指向這個類的執行個體,而且具體的類實作會寫在這個内部類裡面。

    注意:匿名類必須繼承一個父類或實作一個接口。

    不使用匿名内部類來實作抽象方法:

abstract class Person {
    public abstract void eat();
}

class Child extends Person {
    public void eat() {
        System.out.println("eat something");
    }
}

public class Demo {
    public static void main(String[] args) {
        Person p = new Child();
        p.eat();
    }
}      
  1. Java靜态内部類、匿名内部類、成員式内部類和局部内部類

    可以看到,我們用Child繼承了Person類,然後實作了Child的一個執行個體,将其向上轉型為Person類的引用。但是,如果此處的Child類隻使用一次,那麼将其編寫為獨立的一個類豈不是很麻煩?

    這個時候就引入了匿名内部類。使用匿名内部類實作:

1 abstract class Person {
 2     public abstract void eat();
 3 }
 4 
 5 public class Demo {
 6     public static void main(String[] args){
 7        
 8         // 繼承 Person 類
 9         new Person() {
10             public void eat() {
11                 System.out.println("eat something");
12             }
13         }.eat();
14     }
15 }      
  1. Java靜态内部類、匿名内部類、成員式内部類和局部内部類

    可以看到,匿名類繼承了 Person 類并在大括号中實作了抽象類的方法。

    内部類的文法比較複雜,實際開發中也較少用到,并不打算進行深入講解,各位讀者也不應該将内部類作為學習Java的重點。

繼續閱讀