首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 內部類全解析:成員、靜態、匿名與局部內部類深度解析

     編輯:Java 綜合教學

Java 內部類全解析:成員、靜態、匿名與局部內部類深度解析

在 Java 程式設計中,內部類是一項強大且靈活的機制,允許將一個類定義在另一個類的內部。這種結構不僅能實現更好的封裝與隱藏,還能讓內部類直接存取外部類的所有成員(包含私有成員),為解決複雜設計問題(如間接實現多重繼承)提供了優雅的方案。本文將系統性地剖析四種核心內部類型:成員內部類、靜態內部類、匿名內部類與局部內部類,並透過完整程式碼範例說明其特性、限制與實際應用場景。

一、內部類基礎概念與核心特性

內部類的定義形式如下:

public class Outer {
    class Inner {
        // 內部類實作
    }
}

其四大核心特性:

  1. 封裝性優異:可使用 private、protected 等修飾符,實現真正的隱藏。
  2. 無障礙存取外部成員:內部類可直接存取外部類的所有屬性與方法,包含 private 成員。
  3. 外部類需實例化才能存取內部成員:外部類無法直接呼叫內部類成員,必須先建立內部類物件。
  4. 解決多重繼承限制:透過內部類繼承不同父類或實作同名介面方法,間接實現多重繼承效果。

二、成員內部類

定義與特性

成員內部類屬於外部類的實例成員,可擁有 public、private、protected、預設四種權限。在內部類中存取外部類成員時,需使用 外部類名.this.成員 語法。

實例化語法

外部類名.內部類名 實例名 = 外部類實例.new 內部類建構子();

關鍵限制

  • 不可與外部類同名。
  • 不可定義 static 成員(屬性、方法、類),static final 常數除外。因為成員內部類實例必須關聯外部類實例,靜態成員應移至外部類。

程式碼範例:基本用法與多重繼承模擬

public class MemberInnerClass {
    public static void main(String[] args) {
        Outer1 outer = new Outer1();
        Outer1.Inner1 inner = outer.new Inner1();
        inner.innerShow();
        
        System.out.println("--------------外部類訪問內部類對象--------------");
        outer.outerShow();
    }
}

class Outer1 {
    private String name = "張三";
    private int num1 = 10;
    
    public void outerShow() {
        System.out.println(name);
        System.out.println(num1);
        // 外部類需建立內部類物件才能存取
        Inner1 inner = new Inner1();
        inner.innerShow();
    }
    
    public class Inner1 {
        private String name = "李四";
        private int num2 = 20;
        private static final int num3 = 30; // 僅允許 static final 常數
        
        public void innerShow() {
            System.out.println(name);
            System.out.println(num2);
            // 存取外部類成員
            System.out.println(Outer1.this.name);
            System.out.println(Outer1.this.num1);
        }
    }
}

應用場景:間接實現多重繼承

class C {
    private class A1 extends A { public void showA() { super.showA(); } }
    private class B1 extends B { public void showB() { super.showB(); } }
    
    public void showA() { new A1().showA(); }
    public void showB() { new B1().showB(); }
}

應用場景:解決父類與介面同名方法衝突

class Son extends Parent {
    public void show() { System.out.println("抽象類中的show方法"); }
    
    private class Inner2 implements IShow {
        public void show() { System.out.println("介面中的show方法"); }
    }
    
    public void show2() { new Inner2().show(); }
}

三、靜態內部類

定義與特性

使用 static 修飾的成員內部類稱為靜態內部類。它不依賴外部類實例,可視為與外部類平級的獨立類,實例化語法為:

外部類名.內部類名 實例名 = new 外部類名.內部類名();

關鍵限制

  • 不可與外部類同名。
  • 無法存取外部類非靜態成員,外部類也無法直接存取靜態內部類的非靜態成員。

程式碼範例

public class StaticInnerClass {
    public static void main(String[] args) {
        Outer2.Inner2 inner = new Outer2.Inner2();
        inner.innerShow();
        
        Outer2 outer = new Outer2();
        outer.outerShow();
    }
}

class Outer2 {
    private String name = "張三";
    private int num1 = 10;
    private static int num3 = 100;
    
    public void outerShow() {
        System.out.println(name);
        System.out.println(num1);
        Inner2 inner = new Inner2();
        System.out.println(inner.name);     // 存取非靜態需實例
        System.out.println(Inner2.num3);    // 存取靜態直接用類名
    }
    
    public static class Inner2 {
        private String name = "李四";
        private int num2 = 20;
        private static final int num3 = 30;
        
        public void innerShow() {
            System.out.println(name);
            System.out.println(num2);
            // System.out.println(Outer2.this.name); // 編譯錯誤:無法存取非靜態
            System.out.println(Outer2.num3);        // 僅能存取外部類靜態成員
        }
    }
}

四、匿名內部類

定義與特性

  • 無類別名稱,必須在 new 敘述中同時宣告並建立實例。
  • 必須繼承一個類(抽象或具體)或實作一個介面;若父類為抽象,需實作所有抽象方法。
  • 可定義實例初始化區塊 { },但不可定義靜態區塊 static { }。

語法形式

new 介面/父類() {
    // 類別主體:實作方法、定義欄位、初始化區塊
}

程式碼範例:簡化介面實作

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Person person = new Person();
        
        // 直接以匿名類實作 IAnimal 介面
        person.feed(new IAnimal() {
            private String name = "aa";
            { name = "哈哈"; } // 實例初始化區塊
            
            public void eat() { System.out.println("啃骨頭"); }
            public void show() { System.out.println(name); }
        });
        
        // 另一種寫法:建立實例後呼叫自有方法
        new IAnimal() {
            public void eat() { System.out.println("吃魚"); }
            public void show() { System.out.println("匿名類自有方法"); }
        }.show();
    }
}

interface IAnimal { void eat(); }
class Person { public void feed(IAnimal animal) { animal.eat(); } }

五、局部內部類

定義與特性

  • 定義於程式碼區塊、方法內部的類別。
  • 存取外部類成員同樣使用 外部類名.this.成員。
  • 對外部完全隱藏,僅在其作用域內可建立實例。

關鍵限制

  • 不可加存取修飾符(非類成員)。
  • 不可與外部類同名。
  • 存取作用域內的區域變數時,該變數隱性要求為 final(Java 8+ 若未修改值則隱含 final)。

程式碼範例

public class LocalInnerClass {
    public static void main(String[] args) {
        Outer3 outer = new Outer3();
        outer.showOuter();
    }
}

class Outer3 {
    private String name = "張三";
    private int num1 = 10;
    private static int num2 = 20;
    
    public void showOuter() {
        final int num4 = 50; // Java 8 前需显式 final,之後隱含
        
        class Inner3 {
            private int num3 = 30;
            private int num1 = 20; // 遮蔽外部同名變數
            
            public void showInner() {
                System.out.println(num3);
                System.out.println(num1);              // 內部類自身欄位
                System.out.println(Outer3.this.num1);  // 外部類實例欄位
                System.out.println(Outer3.num2);       // 外部類靜態欄位
                System.out.println(num4);              // 方法區域 final 變數
            }
        }
        
        Inner3 inner = new Inner3();
        inner.showInner();
    }
}

六、總結與選型建議

類型適用場景關鍵特徵
成員內部類需長期關聯外部實例、存取私有成員、模擬多重繼承依賴外部實例、可有權限修飾符、不可有 static 成員
靜態內部類邏輯屬於外部類但無需存取非靜態成員、工具類、Builder 模式獨立於外部實例、只能存取外部 static 成員
匿名內部類一次性實作介面/繼承類、事件監聽、執行緒建立、Stream 操作無名、即用即建、可有初始化區塊、無 static 區塊
局部內部類方法內邏輯複雜需封裝、僅在特定作用域使用定義在區塊/方法內、無修飾符、捕獲 final 區域變數

掌握這四種內部類的差異與適用場景,能讓你在設計 Java 類別結構時更靈活地處理封裝、繼承與回呼等需求,寫出更簡潔、可維護的程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved