オブジェクト指向プログラミング(OOP)では、内部クラスまたはネストされたクラスは、別のクラスまたはインターフェースの本体内で完全に宣言されたクラスです。これはサブクラスとは区別されます。
概要
通常クラスまたはトップレベル クラスのインスタンスは、単独で存在できます。対照的に、内部クラスのインスタンスは、トップレベル クラスにバインドされずにインスタンス化することはできません。
Car4 つの を持つという抽象概念を考えてみましょうWheel。 にはWheel、 の一部であることに依存する特定の機能があります。 この概念は、を、任意の車両の一部となり得るより一般的な形式の としてCar表すのではなく、 に固有のものとして表します。 この概念は、次のように内部クラスを使用してモデル化できます。
WheelWheelCar
トップレベル クラス がありますCar。クラスのインスタンスは、Carクラスの 4 つのインスタンスで構成されていますWheel。クラスのこの特定の実装はWheel自動車に固有のものであるため、コードは、トップレベル クラスとして表現した方がよい一般的な車輪の概念をモデル化していません。したがって、クラスに意味的に接続されておりCar、クラスのコードはWheel、自動車の構成単位である外部クラスに何らかの形で結合されています。特定の自動車の車輪はその自動車に固有のものですが、一般化のために、車輪は自動車の集約単位です。
内部クラスは、この接続を正確にモデル化するメカニズムを提供します。WheelクラスをCar.Wheel、Carトップレベルクラス、Wheel内部クラスとして参照できます。
したがって、内部クラスを使用すると、クラスにカプセル化されないプログラムの特定の部分のオブジェクト指向が可能になります。
クラス内のコードの大きなセグメントは、内部クラスではなく、別のトップレベル クラスとしてモデル化またはリファクタリングする方が適している可能性があります。これにより、コードはアプリケーション内でより汎用的になり、再利用性も高まりますが、一般化が時期尚早になる可能性があります。コードに共有機能を持つ内部クラスが多数ある場合は、これがより効果的である可能性があります。
Java のネストされたクラスの種類
Javaには、ネストされたクラスの種類が 4 つあります。
- 静的
- 静的メンバークラス、静的ネストクラスとも呼ばれる[1] – 宣言されます
static。静的スコープ内の他のもの(つまり、静的メソッド)と同様に、これらには囲むインスタンスがなく、囲むクラスのインスタンス変数やメソッドにアクセスできません。スコープの詳細を除いて、ネストされていないクラスとほぼ同じです(名前を修飾せずに囲むクラスの静的変数とメソッドを参照できますが、囲むクラス以外のクラスは、囲むクラスの名前で名前を修飾する必要があります)。ネストされたインターフェースは暗黙的に静的です。
- 非静的/内部クラス
内部クラス – 以下のカテゴリは内部クラスと呼ばれます。これらのクラスの各インスタンスは、静的コンテキストで宣言されたローカルクラスと匿名クラスを除き、囲むインスタンス(つまり、囲むクラスのインスタンス) への参照を持ちます。したがって、それらは囲むクラスのインスタンス変数とメソッドを暗黙的に参照できます。囲むインスタンス参照は、 を介して明示的に取得できますEnclosingClassName.this。内部クラスは、コンパイル時定数変数を除き、静的変数またはメソッドを持つことはできません。内部クラスが作成されると、囲むクラスのインスタンスへの参照を持つ必要があります。つまり、それらは、囲むクラスのインスタンスメソッドまたはコンストラクター内で作成されるか、(メンバークラスと匿名クラスの場合) 構文 を使用して作成される必要がありますenclosingInstance.new InnerClass()。[1]
- メンバー クラス – 関数の外部で宣言され (したがって「メンバー」)、「静的」として宣言されません。
- ローカル クラス – 関数の本体で宣言されるクラスです。関数の残りの部分でのみ参照できます。関数のローカル変数とパラメータを使用できますが、使用できるのは「final」と宣言されているものだけです。(これは、ローカル クラス インスタンスが関数よりも長く存続する可能性があるため、変数の別のコピーを維持する必要があるためです。同じスコープ内に同じ名前の変更可能な変数が 2 つあるという混乱を避けるために、変数は変更不可に強制されます。) ジェネリック型フィールドを持つクラスを作成するときに非常に役立ちます。この場合、型変数はメソッドで定義されます。
- 匿名クラス – これらは、式の途中で自動的に宣言され、インスタンス化されるローカル クラスです。これらは、1 つのクラスを直接拡張するか、1 つのインターフェイスのみを実装できます。スーパークラスのコンストラクターに引数を指定できますが、それ以外の場合はコンストラクターを持つことはできません (ただし、インスタンス初期化ブロックを使用して任意の初期化を実行できるため、これは制限ではありません)。
プログラミング言語
- 内部クラスは、バージョン 1.1 からJava プログラミング言語の機能になりました。
- ネストされたクラスは、 D プログラミング言語、Visual Basic .NET、Ruby、C++、C#の機能でもあります。
- Pythonでは、クラスを別のクラス、メソッド、または関数内にネストすることが可能です。
- C++ には、Java の静的メンバー クラスに似たネストされたクラスがありますが、"static" で宣言されていない点が異なります。
- BETA言語では、ネストされたクラスの概念が導入されました。
GUIコード
ローカル内部クラスは、GUI コードのコールバックを定義するために Java でよく使用されます。コンポーネントは、イベント処理インターフェイスを実装するオブジェクト、または特定のイベントがトリガーされたときに実行されるコードを含む抽象アダプター クラスを拡張するオブジェクトを共有できます。
匿名内部クラスは、イベント処理コードが 1 つのコンポーネントでのみ使用され、名前付き参照を必要としない場合にも使用されます。
actionPerformed(ActionEvent)これにより、イベントのソースを識別するために複数の if-else 分岐を持つ大規模なモノリシック メソッドを回避できます。このタイプのコードは、しばしば乱雑であると考えられており[引用が必要]、内部クラスのバリエーションはあらゆる点で優れていると考えられています。[引用が必要]
参考文献
- ^ ab (Oracle) ネストされたクラス、Oracle.Com – Java チュートリアル。
外部リンク
- 「内部クラス そもそも内部クラスは何の役に立つのでしょうか?」
- D のネストされたクラス
