內部類的分類
內部類的特點
- 可以使用private、protected修飾。也可以使用abstract、final等修飾.
- 內部類可以直接或利用引用訪問外部類的屬性和方法,包括私有屬性和方法(但靜態內部類不能訪問外部類的非靜態成員變量和方法)。內部類所訪問的外部屬性的值由構造時的外部類對象決定.
- 外部類要訪問內部類的成員,則只能通過引用的方式進行,可問內部類所有成員
- 內部類可以繼承同級的內部類,也可繼承其它類(除內部類和外部類)
- 內部類可以定義爲接口,並且可以定義另外一個類來實現它
- 內部類可以定義爲抽象類,可以定義另外一個內部類繼承它
- 方法內的內部類不能加範圍限定(protected public private),方法內的內部類不能加static修飾符,方法內的內部類只能在方法內構建其實,方法內的內部類如果訪問方法局部變量,則此局部變量必須使用final修飾
靜態內部類
測試代碼I
/**
* 類定義時加上static關鍵字。
* 不能和外部類有相同的名字。
* 被編譯成一個完全獨立的.class文件,名稱爲OuterClass$InnerClass.class的形式。
* 只可以訪問外部類的靜態成員和靜態方法,包括了私有的靜態成員和方法。
* 生成靜態內部類對象的方式爲:
* OuterClass.InnerClass inner = new OuterClass.InnerClass();
*/
public class StaticInnerClassTest {
private static String string = "Hello World";
/**
* 靜態內部類可以訪問外部類的靜態成員
* 並且它只能訪問靜態的
*/
private static class StaticInnerClass{
public void test(){
System.out.println(string);
}
}
public static void main(String[] args){
/**
* 無論定義的是private還是public,都可以在外部類使用
*/
StaticInnerClass staticInnerClass = new StaticInnerClass();
staticInnerClass.test();
}
}
測試代碼II
class OuterClass {
private static String string = "Hello World";
/**
* 靜態內部類可以訪問外部類的靜態成員
* 並且它只能訪問靜態的
*/
static class StaticInnerClass {
public void test() {
System.out.println(string);
}
}
}
public class StaticInnerClassTest2 {
public static void main(String[] args) {
/**
* 當內部類是public,protected或者default時,可以在外部定義,
* private聲明的靜態內部類,不能在外面訪問.
*/
OuterClass.StaticInnerClass staticInnerClass = new OuterClass.StaticInnerClass();
staticInnerClass.test();
}
}
成員內部類
測試代碼
/**
* 成員內部類也是定義在另一個類中,但是定義時不用static修飾。
* 成員內部類和靜態內部類可以類比爲非靜態的成員變量和靜態的成員變量。
* 成員內部類就像一個實例變量。
* 它可以訪問它的外部類的所有成員變量和方法,不管是靜態的還是非靜態的都可以。
*/
class MemberInner {
private int d = 1;
private int a = 2;
public class MemberInnerClass {
private int a = 8;
public void doSomething() {
System.out.println(d);
/**
* 直接訪問a,則訪問的是內部類裏的a
*/
System.out.println(a);
/**
如何訪問到外部類裏的a呢?
*/
System.out.println(MemberInner.this.a);
}
}
}
public class MemberInnerClassTest {
public static void main(String[] args) {
/**
*創建成員內部類的對象
* 需要先創建外部類的實例
*/
MemberInner.MemberInnerClass memberInnerClassTest = new MemberInner().new MemberInnerClass();
memberInnerClassTest.doSomething();
}
}
匿名內部類
測試代碼
import java.util.Date;
/**
* 匿名內部類就是沒有名字的局部內部類,不使用關鍵字class, extends, implements, 沒有構造方法。
* 匿名內部類隱式地繼承了一個父類或者實現了一個接口。
* 匿名內部類使用得比較多,通常是作爲一個方法參數。
*/
public class AnonymousInnerClassTest {
@SuppressWarnings("deprecation")
public String getDate(Date date) {
return date.toLocaleString();
}
public static void main(String[] args) {
AnonymousInnerClassTest test = new AnonymousInnerClassTest();
String str = test.getDate(new Date());
System.out.println(str);
/**
* 使用匿名內部類
* 使用了花括號,但是不填入內容,執行結果和上面的完全一致
* 生成了一個繼承了Date類的子類的對象
*/
String str2 = test.getDate(new Date() {
});
System.out.println(str2);
/**
* 使用匿名內部類,並且重寫父類中的方法
*/
String str3 = test.getDate(new Date() {
/**
* 重寫父類中的方法
*/
@Override
@Deprecated
public String toLocaleString() {
return "Hello: " + super.toLocaleString();
}
});
System.out.println(str3);
}
}
局部內部類
測試代碼
/**
* 局部內部類定義在方法中,比方法的範圍還小。是內部類中最少用到的一種類型。
* 像局部變量一樣,不能被public, protected, private和static修飾。
* 只能訪問方法中定義的final類型的局部變量。
* 局部內部類在方法中定義,所以只能在方法中使用,即只能在方法當中生成局部內部類的實例並且調用其方法。
*/
class LocalInner {
int a = 1;
public void doSomething() {
int b = 2;
final int c = 3;
/**
* 定義一個局部內部類
*/
class Inner3 {
public void test() {
System.out.println("Hello World");
System.out.println(a);
/**
* 不可以訪問非final的局部變量,只能訪問final變量
*/
System.out.println(c);
}
}
/**
* 創建局部內部類的實例並調用方法
*/
new Inner3().test();
}
}
public class LocalInnerClassTest {
public static void main(String[] args) {
LocalInner inner = new LocalInner();
inner.doSomething();
}
}