オブジェクト指向プログラミング(OOP)において、内部クラスまたはネストされたクラスとは、別のクラスまたはインターフェースの本体内に完全に宣言されたクラスのことです。これは、別のクラスから派生したサブクラスとは区別されます。
通常クラスまたはトップレベルクラスのインスタンスは、単独で存在できます。一方、内部クラスのインスタンスは、トップレベルクラスにバインドされていない限り、インスタンス化できません。
Car4 つの を持つという抽象的な概念を考えてみましょうWheel。私たちのWheelは、 の一部であることに依存する特定の特徴を持っています。この概念は、 をあらゆる車両の一部になり得るより一般的な形式の として表現するものでCarはありません。代わりに、 に固有のものとして表現します。この概念は、内部クラスを使用して次のようにモデル化できます。WheelWheelCar
最上位クラス がありますCar。 クラスのインスタンスはCar、 クラスの 4 つのインスタンスで構成されますWheel。 この の特定の実装はWheel車に特化しているため、コードは、最上位クラスとして表現する方が適切な一般的なホイールの概念をモデル化していません。したがって、 は意味的にクラス に接続されておりCar、 のコードは、Wheel車の構成単位であるため、何らかの形でその外側のクラスと結合しています。特定の車のホイールはその車に固有のものですが、一般化のために、ホイールは車への集約単位です。
内部クラスは、この関係を正確にモデル化するためのメカニズムを提供します。Wheelクラスを と表記しますCar.Wheel。Carはトップレベルクラス、Wheelは内部クラスです。
class Car { class Wheel { double diameter ; }int doors = 4 ; double maxSpeed ; Wheels [] wheels = new Wheels [ 4 ] ; }したがって、内部クラスを用いることで、本来であればクラスにカプセル化されないプログラムの特定の部分をオブジェクト指向的に扱うことが可能になります。
クラス内のより大きなコード部分は、内部クラスではなく、独立したトップレベルクラスとしてモデル化またはリファクタリングした方が良い場合があります。これにより、コードの汎用性が高まり、再利用性も向上しますが、時期尚早な汎用化となる可能性もあります。コードに共通の機能を持つ内部クラスが多数存在する場合、この方法はより効果的であると考えられます。
Javaには、ネストされたクラスが4種類あります。
static内部クラス–次のカテゴリは内部クラスと呼ばれます。静的コンテキストで宣言されたローカルクラスと匿名クラスを除き、これらのクラスの各インスタンスは、囲んでいるインスタンス(つまり、囲んでいるクラスのインスタンス) への参照を持ちます。したがって、囲んでいるクラスのインスタンス変数とメソッドを暗黙的に参照できます。囲んでいるインスタンスへの参照は、明示的に取得できます。内部クラスは、コンパイル時定数変数を除き、静的変数またはメソッドを持つことはできません。内部クラスが作成されるときは、囲んでいるクラスのインスタンスへの参照を持つ必要があります。つまり、囲んでいるクラスのインスタンスメソッドまたはコンストラクタ内で作成されるか、(メンバクラスと匿名クラスの場合は) 構文を使用して作成される必要があります。[ 1 ] EnclosingClassName.thisenclosingInstance.new InnerClass()
staticfinalJavaでは、ローカル内部クラスはGUIコードのコールバックを定義するためによく使用されます。コンポーネントは、イベント処理インターフェースを実装するオブジェクト、または抽象アダプタクラスを拡張するオブジェクトを共有できます。このオブジェクトには、特定のイベントが発生したときに実行されるコードが含まれています。
匿名内部クラスは、イベント処理コードが1つのコンポーネントのみで使用され、名前付き参照を必要としない場合にも使用されます。
actionPerformed(ActionEvent)これにより、イベントの発生源を特定するために複数のif-else分岐を持つ大規模なモノリシックメソッドを使用することを回避できます。このようなコードはしばしば煩雑であると考えられており、内部クラスのバリエーションの方があらゆる点で優れているとされています。