[TOC]
# 匿名類和內部類
* ## 內部類的范圍
內部類有以下幾種范圍:
### 1. 成員內部類(Member Inner Class)
成員內部類是定義在外部類的成員位置上的類,它可以訪問外部類的所有成員,包括私有成員,也可以被外部類以及其他類訪問。
- 語法格式
~~~
public class Outer { // 定義外部類
public class Inner { // 定義內部類
}
}
~~~
### 2. 靜態內部類(Static Inner Class)
靜態內部類是定義在外部類的靜態成員位置上的類,它不能訪問外部類的非靜態成員,但可以訪問外部類的靜態成員。
- 語法格式
```
public class OuterClass {
private static int outerStaticField;
public static class InnerClass { //定義靜態內部類
}
}
```
### 3. 局部內部類(Local Inner Class)
局部內部類是定義在方法或語句塊內部的類,它只能在該方法或語句塊內部訪問,不能被外部類和其他類訪問。
- 語法格式
```
~~~
public classOuterClass {
public void method() { //定義成員方法
class InnerClass { //定義局部內部類
}
}
}
~~~
```
### 4. 匿名內部類(Anonymous Inner Class)
匿名內部類是一種沒有名字的內部類,它可以用來創建一個只需要使用一次的類。匿名內部類通常用于實現某個接口或繼承某個類,并重寫其中的方法。
- 語法格式
```
new 接口名/類名() {
// 匿名類的成員變量和方法的定義
};
```
## 1. 主要解決了以下幾個問題:
### 1.1. 簡化代碼。
匿名類可以避免編寫完整的類來實現簡單的接口或繼承抽象類,簡化代碼量。內部類可以隱藏實現細節,保持外部類的簡潔性。
```
// 簡化以下代碼
public interface Runnable { // 定義Runnable接口
void run();
}
// 語法格式是實例化接口或類 new 接口名/類名() {}
Runnable runnable = new Runnable() { // 使用匿名內部類實現Runnable接口
@Override
public void run() {
System.out.println("Running...");
}
};
```
需要注意的是,匿名類只能實現一個接口或繼承一個類,而且它沒有構造函數,因此不能在其中初始化成員變量。如果需要實現多個接口或者需要初始化成員變量,可以考慮使用具名的內部類。
*****
### 1.2. 增加封裝性。
內部類可以訪問外部類的私有成員,增加了封裝性。局部內部類的作用域只在方法內,更加封裝。
```
public class Outer { // 定義外部類
private int num = 10; // 私有成員
public class Inner { // 定義內部類
public void show() {
System.out.println(num); // 訪問外部類的私有成員
}
}
}
```
*****
### 1.3. 解決多繼承問題。
Java只支持單繼承,通過內部類可以部分模擬多繼承的效果,一個內部類可以繼承一個類,而外部類可以繼承另一個類。
```
public class Outer { // 定義外部類
public void show() { }
}
public class Outer2 { // 定義另一個外部類
public void display() { }
}
public class Test extends Outer { // 外部類繼承Outer
public class Inner extends Outer2 { // 內部類繼承Outer2
public void print() {
show(); // 調用外部類方法
display(); // 調用內部類方法
}
}
}
```
*****
### 1.4. 隱藏實現細節。
內部類的作用域僅在外部類內,可以隱藏實現細節,保持外部類的簡潔。
```
public class Outer { // 定義外部類
private int num = 10; // 外部類私有成員
public class Inner { // 定義內部類
private int innerNum = 20; // 內部類私有成員
public void show() {
System.out.println(num); // 訪問外部類的私有成員
System.out.println(innerNum); // 訪問內部類的私有成員
}
}
public void display() { // 外部類的方法
Inner inner = new Inner(); // 實例化內部類
inner.show(); // 通過外部類方法間接調用內部類方法
}
}
```
外部類的外部無法直接訪問Inner類的私有成員innerNum,實現細節被隱藏。只有通過Outer類的方法才能間接使用Inner類,這增加了封裝性。
*****
### 1.5. 避免命名空間污染。
使用內部類可以避免在同一個命名空間下定義太多的類,防止命名空間污染。
```
public class Outer { // 定義外部類
public class Inner1 { // 定義內部類1
}
public class Inner2 { // 定義內部類2
}
public class Inner3 { // 定義內部類3
}
}
```
如果不使用內部類,需要在同一個命名空間下定義三個類,這會導致命名空間過于繁雜,內部類可以避免這種情況,防止命名空間污染。
*****
## 2. 匿名類示例——創建線程對象:
使用了匿名類來創建一個`Runnable`對象,重寫了`run`方法,并在其中輸出了一條消息。然后,我們將這個`Runnable`對象傳遞給`Thread`構造函數,創建了一個新的線程對象,并調用`start`方法來啟動該線程。
```
public class AnonymousClassExample {
public static void main(String[] args) {
// 使用匿名類創建一個Runnable對象
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Hello, World!");
}
};
// 使用Runnable對象創建一個線程
Thread thread = new Thread(runnable);
thread.start();
}
}
```
*****
## 3. 內部類示例——迭代器:
定義了一個成員內部類`InnerIterator`,它實現了`Iterator`接口,并重寫了其中的方法。在`InnerClassExample`類中,我們定義了一個`iterator`方法,用于返回一個`InnerIterator`對象。在`main`方法中,我們使用`iterator`方法獲取一個迭代器對象,并使用`while`循環輸出迭代器中的元素。由于`InnerIterator`是`InnerClassExample`的成員內部類,所以它可以訪問`elements`和`size`成員變量。
```
import java.util.Iterator;
public class InnerClassExample {
// 成員變量
private Object[] elements;
private int size;
// 構造方法
public InnerClassExample(Object[] elements) {
this.elements = elements;
this.size = elements.length;
}
// 獲取迭代器對象的方法
public Iterator<Object> iterator() {
return new InnerIterator();
}
// 成員內部類
private class InnerIterator implements Iterator<Object> {
// 成員變量
private int index;
// 構造方法
public InnerIterator() {
this.index = 0;
}
// 判斷是否還有下一個元素
@Override
public boolean hasNext() {
return index < size;
}
// 獲取下一個元素
@Override
public Object next() {
if (hasNext()) {
return elements[index++];
} else {
throw new IndexOutOfBoundsException();
}
}
// 移除當前元素(不支持)
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
// 測試代碼
public static void main(String[] args) {
Object[] elements = {1, 2, 3, 4, 5};
InnerClassExample example = new InnerClassExample(elements);
Iterator<Object> iterator = example.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
```
輸出結果:
```
1
2
3
4
5
```
*****
- 系統設計
- 需求分析
- 概要設計
- 詳細設計
- 邏輯模型設計
- 物理模型設計
- 產品設計
- 數據驅動產品設計
- 首頁
- 邏輯理解
- 微服務架構的關系數據庫優化
- Java基礎架構
- 編程范式
- 面向對象編程【模擬現實】
- 泛型編程【參數化】
- 函數式編程
- 響應式編程【異步流】
- 并發編程【多線程】
- 面向切面編程【代碼復用解耦】
- 聲明式編程【注解和配置】
- 函數響應式編程
- 語法基礎
- 包、接口、類、對象和切面案例代碼
- Springboot按以下步驟面向切面設計程序
- 關鍵詞
- 內部類、匿名類
- 數組、字符串、I/O
- 常用API
- 并發包
- XML
- Maven 包管理
- Pom.xml
- 技術框架
- SpringBoot
- 項目文件目錄
- Vue
- Vue項目文件目錄
- 遠程組件
- 敏捷開發前端應用
- Pinia Store
- Vite
- Composition API
- uniapp
- 本地方法JNI
- 腳本機制
- 編譯器API
- 注釋
- 源碼級注釋
- Javadoc
- 安全
- Swing和圖形化編程
- 國際化
- 精實或精益
- 精實軟件數據庫設計
- 精實的原理與方法
- 項目
- 零售軟件
- 擴展
- 1001_docker 示例
- 1002_Docker 常用命令
- 1003_微服務
- 1004_微服務數據模型范式
- 1005_數據模型
- 1006_springCloud
- AI 流程圖生成
- Wordpress_6
- Woocommerce_7
- WooCommerce常用的API和幫助函數
- WooCommerce的鉤子和過濾器
- REST API
- 數據庫API
- 模板系統
- 數據模型
- 1.Woo主題開發流程
- Filter
- Hook
- 可視編輯區域的函數工具
- 渲染字段函數
- 類庫和框架
- TDD 通過測試來驅動開發
- 編程范式對WordPress開發
- WordPress和WooCommerce的核心代碼類庫組成
- 數據庫修改
- 1.WP主題開發流程與時間規劃
- moho
- Note 1
- 基礎命令