内部クラスの基本概念
あるクラス内部で宣言されるクラスを内部クラスと呼び、これを包含するクラスは外部クラスと呼ばれます。
<code>public class OuterClass {
private int outerId;
private String outerName;
class InnerClass {
// 内部クラス定義
}
}</code>
内部クラスの利用目的
名前空間の衝突回避とカプセル化強化のため、外部クラスの非公開メンバへ直接アクセス可能です。
内部クラスの分類
1. メンバ内部クラス
(1) 標準メンバクラス
<code>class Outer {
class Inner {
// メンバ定義
}
}</code>
- 内部クラスは外部クラスの全メンバ(private含む)に直接アクセス可能
- 外部クラス内で内部クラスメンバにアクセスする際はインスタンス生成が必要
- 外部からアクセス時:
Outer.Inner obj = new Outer().new Inner(); - メンバ名が重複する場合:
OuterClass.this.outerIdで外部クラス変数を参照
(2) 非公開メンバクラス
<code>public class Teacher {
private class Student {
private int grade;
}
public void accessGrade() {
Student s = new Student();
System.out.println(s.grade);
}
}</code>
- 外部クラス内でのみインスタンス化可能
- 外部からは公開メソッド経由で間接アクセス
(3) 静的メンバクラス
<code>public class Network {
static final int TIMEOUT = 1000;
static class Connection {
void connect() {
System.out.println(TIMEOUT);
}
}
}</code>
- 静的メンバのみ外部クラスからアクセス可能
- 外部からのインスタンス化:
Network.Connection conn = new Network.Connection(); - 非静的メンバにはオブジェクト生成必須
2. ローカル内部クラス
<code>public class Processor {
private int counter = 0;
public void execute(final int param) {
final int localVar = 10;
class Task {
void run() {
System.out.println(counter + param + localVar);
}
}
new Task().run();
}
}</code>
- メソッド内でのみ有効なスコープ
- 外部クラス変数とメソッド引数(final修飾必須)にアクセス可能
- Java 8以降はfinal暗黙指定
3. 匿名内部クラス
<code>button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("イベント処理実行");
}
});</code>
- インターフェース/抽象クラスの単一メソッド実装に適用
- インスタンス生成とメソッド実装を同時に実行