Javaネストクラスとインナークラス完全ガイド:種類、例、ベストプラクティス
Javaネストクラスとインナークラス
Javaのネストクラスがカプセル化を強化し、可読性を向上させ、強力なインナークラスパターンを可能にする仕組みを発見してください。
Javaではクラス内に別のクラスを宣言できます——これをネストクラスと呼びます。例えば:
class OuterClass { // ... class NestedClass { // ... } }
ネストクラスには2つの主要な種類があります:
- 非staticネストクラス(一般にインナークラスと呼ばれる)
- Staticネストクラス
推奨読書:
- Javaアクセス修飾子
- Java Staticキーワード
非Staticネストクラス(インナークラス)
インナークラスは外部クラス内に存在し、外部クラスのメンバ(privateでさえ)に自由にアクセスできます。外部クラスのインスタンスに結びついているため、まず外部クラスをインスタンス化する必要があります。
例1:インナークラス
class CPU { double price; // インナークラス class Processor{ double cores; String manufacturer; double getCache(){ return 4.3; } } // protectedインナークラス protected class RAM{ double memory; String manufacturer; double getClockSpeed(){ return 5.5; } } } public class Main { public static void main(String[] args) { CPU cpu = new CPU(); CPU.Processor processor = cpu.new Processor(); CPU.RAM ram = cpu.new RAM(); System.out.println("Processor Cache = " + processor.getCache()); System.out.println("Ram Clock speed = " + ram.getClockSpeed()); } }
出力:
Processor Cache = 4.3 Ram Clock speed = 5.5
ここでは、ProcessorとRAMがCPU内にネストされています。RAMクラスがprotectedで宣言されており、インナークラスがJavaのあらゆるアクセス修飾子を使用できることを示しています。
Mainでは、まず外部クラスCPUをインスタンス化し、外部インスタンス経由でインナークラスインスタンスを作成します:
CPU.Processor processor = cpu.new Processor; CPU.RAM ram = cpu.new RAM();
ヒント: ドット(.)演算子でインナークラスインスタンスを外部インスタンスに結びつけます。
インナークラスから外部クラスメンバへのアクセス
インナークラスは、外部クラス名をプレフィックスとしたthisキーワードで外部クラスのメンバを参照できます(例:Car.this.carType)。インナークラス独自のthisコンテキストがある場合、この構文が必要です。
例2:外部クラスとの相互作用
class Car { String carName; String carType; public Car(String name, String type) { this.carName = name; this.carType = type; } private String getCarName() { return this.carName; } // インナークラス class Engine { String engineType; void setEngine() { if(Car.this.carType.equals("4WD")){ if(Car.this.getCarName().equals("Crysler")) { this.engineType = "Smaller"; } else { this.engineType = "Bigger"; } } else { this.engineType = "Bigger"; } } String getEngineType(){ return this.engineType; } } } public class Main { public static void main(String[] args) { Car car1 = new Car("Mazda", "8WD"); Car.Engine engine = car1.new Engine(); engine.setEngine(); System.out.println("Engine Type for 8WD= " + engine.getEngineType()); Car car2 = new Car("Crysler", "4WD"); Car.Engine c2engine = car2.new Engine(); c2engine.setEngine(); System.out.println("Engine Type for 4WD = " + c2engine.getEngineType()); } }
出力:
Engine Type for 8WD= Bigger Engine Type for 4WD = Smaller
getCarName()がprivateでも、インナークラスは同じ外部クラス内にあるため呼び出せます。
Staticネストクラス
Staticネストクラスは外部クラスのインスタンスを必要としません。したがって、外部クラスの非staticメンバに直接アクセスできません。外部クラス名で作成します:
OuterClass.NestedClass obj = new OuterClass.NestedClass();
例3:Staticネストクラス
class MotherBoard { static class USB{ int usb2 = 2; int usb3 = 1; int getTotalPorts(){ return usb2 + usb3; } } } public class Main { public static void main(String[] args) { MotherBoard.USB usb = new MotherBoard.USB(); System.out.println("Total Ports = " + usb.getTotalPorts()); } }
出力:
Total Ports = 3
例4:Staticネストクラスで外部メンバへのアクセスを試みる
class MotherBoard { String model; public MotherBoard(String model) { this.model = model; } static class USB{ int usb2 = 2; int usb3 = 1; int getTotalPorts(){ if(MotherBoard.this.model.equals("MSI")) { return 4; } else { return usb2 + usb3; } } } } public class Main { public static void main(String[] args) { MotherBoard.USB usb = new MotherBoard.USB(); System.out.println("Total Ports = " + usb.getTotalPorts()); } }
このコードを実行すると:
error: non-static variable this cannot be referenced from a static context
このエラーは、staticネストクラスが外部インスタンスなしでMotherBoard.thisを参照できないため発生します。
重要なポイント
- インナークラスは外部クラスの通常メンバとして扱われ、
private、protected、publicで宣言可能。 - 外部クラスのすべてのメンバに自由にアクセス可能、
privateでさえも。 - Staticネストクラスは外部インスタンスを必要とせず、非static外部メンバに直接アクセスできない。
- ネストクラスの使用はカプセル化を促進し、関連ロジックをまとめる。
- インナークラスはコールバック、リスナー、外部クラスと密結合なヘルパーオブジェクトに最適。
Java
- C# 入れ子クラスを理解する:定義、使用法、継承
- Java変数とリテラル:包括的ガイド
- Javaクラスとオブジェクト:実践ガイド
- Javaのfinalキーワード完全解説:変数、メソッド、クラスでの活用法
- Java instanceof演算子完全ガイド:基本から継承・インターフェースまで
- Java抽象クラスとメソッド:包括的ガイド
- Java Staticネストクラスの理解:用法、違い、実例
- Java無名インナークラス完全ガイド:定義、構文、実践例
- Javaシングルトンパターン完全解説:安全な実装と活用法
- Javaリフレクション完全ガイド:実行時のクラス・メソッド・フィールド検査
- Javaジェネリクス完全ガイド:再利用可能で型安全なコードの構築