內部類
在一個類裏面定義的類叫內部類,內部類之外的類叫外部類
分爲:普通內部類、局部內部類、靜態內部類、匿名內部類
成員內部類
成員內部類可以用private、protected、public修飾
成員內部類可以訪問外部類的所有成員屬性和成員方法(包括private成員和靜態成員)
當成員內部類擁有和外部類同名的成員變量或者方法時,會發生隱藏現象,即默認情況下訪問的是成員內部類的成員。如果要訪問外部類的同名成員,需要以下面的形式進行訪問:外部類.this.成員變量,外部類.this.成員方法
成員內部類不能定義靜態變量,靜態方法
成員內部類中不能定義靜態方法(所以成員內部類中沒有main方法)
成員內部類是依附外部類而存在的,也就是說,如果要創建成員內部類的對象,前提是必須存在一個外部類的對象
在外部類中如果要訪問成員內部類的成員,必須先創建一個成員內部類的對象,再通過指向這個對象的引用來訪問
可以定義成員抽象內部類,抽象內部類的抽象方法不能用private、final、static修飾
靜態內部類
靜態內部類只能調用外部類的靜態方法和靜態屬性
靜態內部類不用產生外部類的實例化對象即可產生內部類的實例化對象
靜態內部類也可以用private、protected、public修飾
靜態內部類可以定義非靜態方法和靜態方法,也可以定義靜態屬性和非靜態屬性
可以定義靜態抽象內部類,靜態內部類的抽象方法不能用private、final、static修飾
靜態內部類中可以有main()方法並且可以執行
靜態內部類與非靜態內部類的區別?
1) 是否能擁有靜態成員
靜態內部類可以有靜態成員(方法,屬性),而非靜態內部類則不能有靜態成員(方法,屬性)。
2) 訪問外部類的成員
靜態內部類只能夠訪問外部類的靜態成員,而非靜態內部類則可以訪問外部類的所有成員(方法,屬性)。
3) 靜態內部類和非靜態內部類在創建時有區別
靜態內部類通過外部類的類名實例化,非靜態內部類只能通過外部類實例創建
局部內部類
局部內部類和匿名內部類只能訪問局部final變量
局部內部類就像是方法裏面的一個局部變量一樣,是不能有public、protected、private以及static修飾符
方法內部類不能使用訪問控制符和 static 修飾符
匿名內部類
匿名內部類也是不能有訪問修飾符和static修飾符的,匿名內部類是唯一一種沒有構造器的類。正因爲其沒有構造器,所以大部分匿名內部類用於接口回調。
一般來說,匿名內部類用於繼承其他類或是實現接口,並不需要增加額外的方法,只是對繼承方法的實現或是重寫。
內部類實例
public class OuterClass {
private String name = "YCY";
private static int age = 18;
public void say() {
System.out.println("OuterClass say()");
}
/**
* · 普通內部類
*/
class InnerClass {
// 內部類不能有靜態方法和靜態變量
// static int number = 100;
// static void test() { }
public void say() {
System.out.println("我的名字:" + name );
System.out.println("我的年齡:" + age);
OuterClass.this.say();
}
}
/**
* · 局部內部類
* · 不加修飾符public private
* · 內部中使用外部方法的局部變量,該局部變量必須是final(JDK1.7有要求,JDK1.8不是必須的)
*/
public void speak() {
String classroom = "004班";
// 局部內部類
class InnerClass{
public void tell() {
System.out.println("我的名字:" + name );
System.out.println("我的年齡:" + age);
System.out.println("我的班級:" + classroom);
}
}
// 調用局部內部類中的方法
new InnerClass().tell();
}
/**
* · 靜態內部類
* · 訪問外部類成員必須是靜態的
* · 靜態內部類不可以用 private 來定義
*/
private static String school = "CCIT";
public static class StaticInnerClass {
public void say() {
// 訪問外部類成員必須是靜態的
// System.out.println("我的名字:" + name );
System.out.println("我的年齡:" + age);
// System.out.println("我的班級:" + classroom);
System.out.println("我的學校:" + school);
}
public static void speak() {
// System.out.println("我的名字:" + name );
System.out.println("我的年齡:" + age);
// System.out.println("我的班級:" + classroom);
System.out.println("我的學校:" + school);
}
}
public static void main(String[] args) {
// 方法一創建普通內部類
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass02 = outerClass.new InnerClass();
// 方法二創建普通內部類
InnerClass innerClass01 = new OuterClass().new InnerClass();
innerClass01.say();
// 使用局部內部類的
OuterClass outerClass2 = new OuterClass();
outerClass.speak();
// 使用靜態內部類的靜態方法
OuterClass.StaticInnerClass.speak();
// 使用靜態內部類的非靜態方法
OuterClass outerClass3 = new OuterClass();
new OuterClass.StaticInnerClass().say();//創建匿名對象調用
/**
* · 匿名內部類
* · 無構造方法,使用有限
* · 使用外部方法中的局部變量,局部變量必須是finnal(JDK1.8 不需要finnal)
* · 匿名內部類中的方法必須是重寫外部類的方法,不能調用局部內部類中特有的方法
*/
OuterClass outerClass4 = new OuterClass() {
String sex = "男";
public void say() {
System.out.println("AnonymousClass say()");
System.out.println(sex);
}
public void tell() {
System.out.println("匿名內部類特有方法");
}
};
// 調用局部內部類的方法
outerClass4.say();
// 不能調用局部內部類中特有的方法
// outerClass4.tell();
}
}