天天看點

Java 嵌套類(Nested Class):靜态嵌套類,内部類,局部類,匿名類



       将一個人比作類,人由大腦、肢體、器官等組成,而嵌套類相當于其中的某個器官,例如心髒:它也有自己的屬性和行為(血液、跳動)。

嵌套類(Nested Class)的結構:

//外部類

class Out {

    private int age = 12;
    //嵌套類
    class In {
        public void print() {
            System.out.println(age);
        }
    }
}

 

public class Demo {

    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();

        //或者采用下種方式通路
        /*
        Out out = new Out();

        Out.In in = out.new In();

        in.print();
        */
    }
}
           

運作結果:12

嵌套類的好處:

1 在邏輯上分組隻在一個地方使用的類

2 增加了封裝性(encapsulation)

3 使代碼可讀性更強、更易維持

嵌套類分為:靜态嵌套類(static nested class)和非靜态嵌套類(non-static nested class),後者也稱内部類(inner class)。

例1. 靜态嵌套類

class Out {

    private static int age = 12;
    static class In {
        public void print() {
            System.out.println(age);
        }
    }
}

 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out.In();
        in.print();
    }

}
           

運作結果: 12

說明:如果用static 将内部内靜态化,那麼内部類就隻能通路外部類的靜态成員變量,具有局限性。其次,因為内部類被靜态化,是以Out.In可以當做一個整體看,可以直接new 出内部類的對象。

例2. 内部類

class Out {

    private int age = 12;
    class In {
        private int age = 13;
        public void print() {
            int age = 14;
            System.out.println("局部變量:" + age);
            System.out.println("内部類變量:" + this.age);
            System.out.println("外部類變量:" + Out.this.age);
        }
    }
}

 

public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
    }
}
           

運作結果:

局部變量:14

内部類變量:13

外部類變量:12

可以發現,内部類在沒有同名成員變量和局部變量的情況下,内部類會直接通路外部類的成員變量,而無需指定Out.this.屬性名

否則,内部類中的局部變量會覆寫外部類的成員變量。

而通路内部類本身的成員變量可用this.屬性名,通路外部類的成員變量需要使用Out.this.屬性名。

另外還有兩種特殊的内部類:局部類(local class)和匿名類(anonymous class)

局部類是定義在代碼塊中的類,通常是在一個方法内,稱作方法内部類。

匿名類的申明與執行個體化是同時完成的,它與局部類很相似,除了沒有名字之外。

例3. 局部類

class Out {

    private int age = 12;
    public void print(final int x) {
        class In {
            public void inPrint() {
                System.out.println(x);
                System.out.println(age);
            }
        }

        new In().inPrint();
    }
}

 

public class Demo {

    public static void main(String[] args) {
        Out out = new Out();
        out.print(3);
    }
}
           

運作結果:

3

12

在上面的代碼中,将内部類移到了外部類的方法中,然後在外部類的方法中再生成一個内部類對象去調用内部類方法。

例4. 匿名類

public class OutClasses {
  
    interface HelloWorld {
        public void greetSomeone(String someone);
    }
  
    public void sayHello() {
        
        HelloWorld germanGreeting = new HelloWorld() {//這裡申明了一個匿名類,它的執行個體是germanGreeting
            String name = "mundo";
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hallo, " + name);
            }
        };
        germanGreeting.greetSomeone("Sommer");
    }

    public static void main(String... args) {
        OutClasses myApp = new OutClasses();
        myApp.sayHello();
    }            
}
           

運作結果:Hallo,Sommer

匿名類是一個表達式(分号結尾),常見于GUI應用程式中。它的文法類似于調用構造器,差別在于該類的定義緊跟其後。沒有class關鍵字,如何判斷匿名類呢?

1)要有new 這個操作符,類似正常類執行個體化的表達式。

2)要實作一個接口或繼承一個類,上面的例子是實作HelloWorld這個接口。

3)類體(body),可以在其中定義域、方法,甚至局部類,但是不能定義構造器,也不能有語句(statement)。

本文部分參考Nerxious的部落格 http://www.cnblogs.com/nerxious/archive/2013/01/24/2875649.html