今天温习一下 Java 中的內部類,內部類一般有如下幾種:靜態內部類、成員內部類、匿名內部類和方法內部類,下文中將主要介紹靜態內部類和成員內部類,主要內容如下:
- 概述
- 靜態內部類
- 成員內部類
- 匿名內部類和方法內部類
- 總結
概述#
顧名思義內部類就是在一個類內部定義的類,它是內部類是一個獨立的類,編譯之後會生成獨立的 .class 文件,其名稱前面會有外部類的類名稱以及 $ 符號,內部類同樣可以使用 private 、default、protected、public 修飾,下面是內部類的寫法,具體參考如下:
/**
* 內部類
* @author jzman
*/
public class OutterClass {
//靜態內部類
private static class StaticInnerClass{
}
//成員內部類
private class FieldInnerClass{
}
//匿名內部類
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
private void method() {
//方法內部類(局部內部類)
class InnerClass{
}
}
}
靜態內部類#
- 靜態內部類可以有靜態成員和非靜態成員;
- 靜態內部類可以直接調用外部類的靜態成員和靜態方法,但不能調用外部類的非靜態成員和非靜態方法;
- 在不相關類中,可以直接創建靜態內部類的對象;
- 靜態內部類與其外部類聯繫很少,其創建基本不依賴於外部類。
/**
* 靜態內部類範例
* @author jzman
*/
public class StaticInnerClassDemo {
public static void main(String[] args) {
//其他類可以直接創建某個非私有內部類的實例
OutterClass1.InnerClass innerClassB = new OutterClass1.InnerClass();
InnerClass innerClassA = new InnerClass();
innerClassA.testStaticInnerClass();
//...
}
}
//外部類
class OutterClass1{
//非靜態成員變量
int ageA = 18;
//非靜態方法
public void methodA() {
}
//靜態成員變量
static int ageB = 18;
//靜態方法
public static void methodB() {
}
private void methodC() {
//外部類調用靜態內部類的方法
InnerClass innerClass = new InnerClass();
innerClass.testStaticInnerClass();
}
//靜態內部類
static class InnerClass{
public void testStaticInnerClass(){
//靜態內部類不能訪問其外部類的非靜態成員變量和方法
// System.out.println(ageA);
// methodA();
//靜態內部類可以訪問其外部類的靜態成員和方法
System.out.println(ageB);
methodB();
}
}
}
成員內部類#
- 成員內部類可以訪問所有外部類的成員;
- 成員內部類對象的創建必須依賴於外部類對象,先有外部類才會有內部類;
- 成員內部類就是外部類的一個成員變量;
- 成員內部類不能有靜態成員,但允許常量存在。
/**
* 成員內部類範例
* @author jzman
*/
public class FieldInnerClassDemo {
public static void main(String[] args) {
//成員內部類依賴於其外部類,不能越過外部類直接創建內部類的實例
// InnerClass innerClass = new InnerClass();
//正確在其他類創建內部類的實例
OutterClass2 outterClass2 = new OutterClass2();
OutterClass2.InnerClass innerClass = outterClass2.new InnerClass();
innerClass.testFieldInnerClassMethod();
}
}
//外部類
class OutterClass2{
//非靜態成員變量
int ageA = 18;
//非靜態方法
public void methodA() {
}
//靜態成員變量
static int ageB = 18;
//靜態方法
public static void methodB() {
}
private void methodC() {
//外部類調用成員內部類的方法
InnerClass innerClass = new InnerClass();
innerClass.testFieldInnerClassMethod();
}
//成員內部類
class InnerClass{
//成員內部類不能有靜態成員
// static int a = 10;
//成員內部類允許常量形式存在
static final int b = 10;
public void testFieldInnerClassMethod(){
//成員內部類可以直接訪問其外部類的所有成員變量及方法(靜態和非靜態)
System.out.println(ageA);
methodA();
System.out.println(ageB);
methodB();
}
}
}
匿名內部類和方法內部類#
匿名內部類當然是沒有確定的名稱,其實現都是在類體中具體實現,最終返回相關類的一個匿名對象,由於最終返回的是一個匿名的實例,所以必須在匿名內部類之後添加分號。方法內部類就是局部內部類,一般定義在類的局部位置,它可以訪問當前代碼塊及外部類的所有變量。
總結#
類之間的成員變量的互相調用實際上還是訪問對象的成員變量,如成員內部類能夠訪問外部類的成員變量或方法是因為內部類持有外部類的引用,一般通過 OutterClass.this 獲取外部類的對象,如果外部類想要訪問內部類的成員變量或方法當然也需要持有內部類的引用,所以外部類訪問內部類的成員變量或方法時,必須先創建內部類的對象,然後通過對象來方位相應的成員變量或方法。