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