[TOC]
>[success] # 內部類
當**一個類的定義**出現在**另外一個類的類體**中時,那么這個類叫做**內部類(Inner)**,而這個內部類**所在的類**叫做**外部類(Outer)**
**內部類**和其他類中可聲明使用的內容都一樣,只是作為一種`類形式的成員變量`,類中的內容(**成員變量、成員方法、構造方法、靜態成員、構造塊和靜態代碼塊、內部類**)
>[info] ## 內部類作用
**當一個類**存在的價值**僅僅是為某一個類單獨服務**時,那么就可以將這個類定義為所服務類中的內部類,這樣可以**隱藏該類的實現細節**并且可以方便的訪問外部類的私有成員而**不再需要提供公有的get和set方法**
>[info] ## 內部類種類
1. **普通內部類** \- 直接將一個類的定義放在另外一個類的類體中。
2. **靜態內部類** \- 使用static關鍵字修飾的內部類,隸屬于類層級。
3. **局部內部類** \- 直接將一個類的定義放在方法體的內部時。
4. **匿名內部類** \- 就是指沒有名字的內部類
>[warning] ### 普通(成員)內部類
* 寫法格式
~~~
`訪問修飾符` class `外部類的類名` {
`訪問修飾符` class `內部類的類名` {
內部類的類體;
}
}
~~~
* 調用內部類
1. 如果**內部類是public 修飾的成員** 先創建外部類
2. 聲明的內部類類型 **`外部類.內部類` 變量名 = `外部類聲明對象.new` `內部類()`**
例如下面案例
~~~
// 創建外部類
Outer outer = new Outer();
// 執行內部類
Outer.Inner inner = outer.new Inner();
// 調用 內部類show 方法
inner.show();
~~~
>[danger] ##### 代碼
~~~
package task10;
/**
* 實現普通內部類
* */
public class Outer {
public int num = 1;
// 定義內部類
public class Inner{
// 定義內部變量
public int innerNum = 10;
// 內部類構造方法
public Inner(){
System.out.println("執行內部構造方法");
}
public void show(){
// 打印外部變量
System.out.println("外部num變量:"+num); // 1
System.out.println("內部變量innerNum:" + innerNum); // 10
}
}
}
~~~
* 調用
~~~
public class ExecuteOuter {
// 執行入口
public static void main(String[] args){
// 創建外部類
Outer outer = new Outer();
// 執行內部類
Outer.Inner inner = outer.new Inner();
// 調用 內部類show 方法
inner.show();
}
}
~~~
>[danger] ##### 使用特點
1. 普通內部類和普通類一樣可以定義**成員變量、成員方法以及構造方法等**
2. 普通內部類和普通類一樣可以使用**final或者abstract關鍵字修飾**也可以使用**private或protected**關鍵字進行修飾。
~~~
/*private*/public /*final*/ class Inner{ }
~~~
3. 普通內部類需要使用**外部類對象來創建對象**。
~~~
// 創建外部類
Outer outer = new Outer();
// 執行內部類
Outer.Inner inner = outer.new Inner();
// 調用 內部類show 方法
inner.show();
~~~
4. 如果內部類訪問外部類中與本類內部同名的成員變量或方法時,需要使用**this關鍵字**。作用域就近原則,此時最近的是函數的形參,在其次this表示當前內部類,想用外部類需要 `外部類.this.變量` 調用
~~~
/**
* 實現普通內部類
* */
public class Outer {
public int num = 1;
// 定義內部類
/*private*/public /*final*/ class Inner{
// 定義內部變量
public int innerNum = 10;
public int num = 2;
// 內部類構造方法
public Inner(){
System.out.println("執行內部構造方法");
}
public void show(int num){
// 打印外部變量
System.out.println("此時接受是調用傳進來的num:"+num); // 此時接受是調用傳進來的num
System.out.println("內部類中num:" + this.num); // 2
System.out.println("外部類中的num:" + Outer.this.num); // 1
}
}
}
~~~
**注**:簡單說(他就是一個寫在類里的類,用法特性和類都一樣)。
>[warning] ### 靜態內部類
* 寫法格式
~~~
`訪問修飾符` class `外部類的類名` {
` 訪問修飾符 static` class `內部類的類名` {
內部類的類體;
}
}
~~~
* 調用靜態內部類
~~~
外部類.內部類 對象名 = new 外部類.內部類();
~~~
>[danger] ##### 使用特點
1. 靜態內部類不能直接訪問外部類的非靜態成員。
2. 靜態內部類在使用時候可以直接創建對象。例如:
OuterStatic.InnerStatic innerStatic = new OuterStatic.InnerStatic();
3. 如果靜態內部類訪問外部類中與本類內同名的成員變量或方法時,需要**使用類名.的方式訪問**。
>[danger] ##### 代碼
~~~
public class OuterStatic {
public int a = 1;
public static int b = 2;
public int c = 999;
public static int d = 1000;
// 創建靜態內部類
public static class InnerStatic {
// 內部類屬性
public int a = 3;
public static int b = 4;
public void show() {
// System.out.println(c); // error: 靜態內部不能直接外部類的非靜態成員
System.out.println(d); // 訪問外部類靜態屬性 1000
System.out.println(a + "----" + b); // 就近原則訪問內部 3----4
// 如果靜態內部類訪問外部類中與本類內同名的成員變量或方法時,需要使用類名.的方式訪問
System.out.println(OuterStatic.b); // 2
}
}
}
~~~
* 調用
~~~
public class TestOuterStatic {
public static void main(String[] args) {
OuterStatic.InnerStatic innerStatic = new OuterStatic.InnerStatic();
innerStatic.show();
}
}
~~~
>[warning] ### 局部內部類
* 注:局部內部類與局部變量一樣,不能使用訪問控制修飾符(public、private 和 protected)和 static 修飾符修飾。
~~~
訪問修飾符 class 外部類的類名 {
訪問修飾符 返回值類型 成員方法名(形參列表) {
(這里沒有修飾符)class 內部類的類名 {
內部類的類體;
}
}
}
~~~
* 使用局部內部類只在當前方法中有效
>[danger] ##### 特點
1. 局部內部類只能在該方法的內部可以使用。
2. 局部內部類可以在方法體內部直接創建對象。
3. 局部內部類不能使用訪問控制符和static關鍵字修飾符。
4. 局部內部類可以使用外部方法的局部變量,但是必須是final的。由局部內部類和局部變量的聲明周期不同所致。如下圖雖然局部變量在局部類中使用時候會默認加上final,但如果賦值此時不符合final 定義變量,局部類中會報錯

5. 如果方法中的成員與外部類中的成員同名,則可以使用 .this. 的形式訪問外部類中的成員。
>[danger] ##### 案例
~~~
import java.security.PublicKey;
public class FunInner {
// 外部類變量
int a = 1;
int b = 2;
public void show() {
// 局部變量
int d = 3; // 如果局部 內部局部類使用該屬性默認會加上final 即final int d = 3,如果只局部類使用最好加final 修飾
// 定義局部內部類,局部內部類不能使用訪問控制符和static關鍵字修飾符
class FInner {
// static int b = 2; // 內部不能不能定義 static 成員
int a = 11;
int c = 4;
public void show() {
System.out.println(a + "---" + b + "----" + c); // 就近原則 11---2----4
System.out.println(FunInner.this.a); // 訪問外部同名 1
System.out.println(d); // 訪問局部 3
// d = 36; // error在局部內部類中只可以訪問當前方法中 final 類型的參數與變量,final 變量不能重新賦值
}
}
FInner fInner = new FInner();
fInner.show();
}
public static void main(String[] args) {
FunInner funInner = new FunInner();
funInner.show();
}
}
~~~
- windows -- 環境變量
- Vscode -- 編寫java
- 初始java
- java -- 關鍵字
- 編寫第一個java程序
- java -- 注釋
- 計算機存儲 -- 進制
- java -- 類型
- java -- 變量
- 數字類型
- 布爾類型
- 字符類型
- 類型轉換
- 雙等比較是什么
- java -- 運算符
- 算數運算符
- 字符串拼接
- 關系/比較運算符
- 自增減運算符
- 邏輯運算符
- 三目運算
- 賦值運算符
- 移位運算符
- 位運算符
- 運算符優先級
- java -- 流程控制語句
- if /else if /if -- 判斷
- switch case分支結構
- for -- 循環
- 用雙重for循環
- while -- 循環
- do while -- 循環
- 案例練習
- java -- 數組
- 數組的存儲
- 數組的增刪改查
- 數組的特點
- 數組案例
- 二維數組
- 數組的工具方法
- java -- 方法
- java -- 方法的重載
- java -- 方法的調用流程
- java -- 類方法傳參注意事項
- java -- 方法練習案例
- 對比 return break continue
- for each循環
- java -- 基礎練習
- java -- 面向對象
- java -- 創建類和對象
- java -- 訪問控制符
- java -- 類成員方法
- java -- 構造方法
- java -- this
- java -- 封裝
- java -- 對象內存圖
- java -- 創建對象案例
- java -- static
- java -- 繼承
- super -- 關鍵字
- java -- 構造塊和靜態代碼塊
- java -- 重寫
- java -- final
- java -- 多態
- java -- 抽象類
- java -- 接口
- 引用類型數據轉換
- 綜合案例
- java -- 內部類
- java -- 回調模式
- java -- 枚舉類型
- java -- switch 使用枚舉
- java -- 枚舉方法使用
- java -- 枚舉類實現接口
- java -- javaBean
- java -- package 包
- java -- import
- java -- 遞歸練習
- java -- 設計模式
- 單例模式
- java -- 注解
- java -- 元注解
- Java -- 核心類庫
- java -- 處理字符串
- Java -- String
- String -- 常用方法
- String -- 正則
- Java -- StringBuilder 和 StringBuffer
- 知識點
- Java -- StringJoiner 字符串拼接
- 練習題
- 字符串的總結
- Java -- 包裝類
- Integer
- Double
- Boolean
- Character
- java -- 集合類
- java -- util.Collection
- Iterator接口
- java -- util.List
- java -- ArrayList
- java -- util.Queue
- java -- util.Set
- java -- util.Map
- java -- util.Collections
- Java -- Math
- Java -- java.lang
- Java -- Object
- Java -- 獲取當前時間戳
- Java -- 異常
- Java -- java.util
- java -- Date
- java -- Calender
- Java -- java.text
- Java -- SimpleDateFormat
- Java -- java.time
- Java -- java.io
- java -- io.File
- java -- 泛型
- IDEA -- 用法