たとえば、クラスとその機能の一部を実行するヘルパークラスがある場合、それを内部クラスとして作成するのは理にかなっています。
public class Foo {
private FooHelper helper;
// constructor & any other logic
public void doSomeThing() {
helper.do();
}
}
public class FooHelper {
public void do() {
// code
}
}
上記の場合、FooHelper
を内部クラスとして作成するのは理にかなっていますか?これは馬鹿げているように聞こえますが、ユースケースについては少し混乱していますが、おApび申し上げます。
はい、内部クラスにすることは完全に理にかなっています。他のクラスで必要ない場合は、プライベートにします。外部クラスのメンバーへの排他的アクセスを必要としない場合は、必要なメモリ領域が少なくなるため、静的なネストされたクラスにします。
公式チュートリアル からの推奨事項を確認してください-
囲んでいるインスタンスの非パブリックフィールドおよびメソッドへのアクセスが必要な場合は、非静的なネストされたクラス(または内部クラス)を使用します。このアクセスが必要ない場合は、静的なネストされたクラスを使用します。
FooHelper
がまったく役に立たないFoo
以外の他のクラスであると考える場合、private
Foo
の内部クラス。この種の設計の一例は、プライベート内部クラスHashMap
を定義するKeySet
にあります。
それ以外の場合は、private
インスタンスとして持っているのは良いことです。
From Java SE Docs
ネストされたクラスを使用する理由
1つの場所でのみ使用されるクラスを論理的にグループ化する方法ですクラスが他の1つのクラスにのみ有用である場合、そのクラスに組み込み、2つをまとめるのが論理的です。このような「ヘルパークラス」をネストすると、パッケージがより合理化されます。
カプセル化を増やします: 2つのトップレベルクラスAとBを考えます。Bは、そうでなければプライベートと宣言されるAのメンバーにアクセスする必要があります。クラスA内でクラスBを非表示にすることにより、Aのメンバーはプライベートと宣言され、Bはそれらにアクセスできます。さらに、B自体を外界から隠すことができます。
はい、内部クラスとしてFooHelperを使用するのが理にかなっています。
以下は、内部クラスの使用例です。
したがって、上記のポイントに一致する要件がある場合は、内部クラスを使用できます。他のクラスからのアクセスを防ぐために、常に内部クラスprivate
を作成することをお勧めします。あなたの場合、内部クラスを使用すると、外部クラスでコードを読み取り可能にし、別のロジックを作成するのに役立ちます。
内部クラスは、小さくて名前を必要としない場合に意味があります。 GUIのリスナーは、理にかなっている典型的な例です。
クラスが大きくて重要な場合は、名前を付けて別のファイルに配置する必要があります。
通常のGUIの例のリスナークラスは、1つの小さなことを行います。通常、実際の作業を行うために他の関数にディスパッチするだけです。
また、別のクラスのコンテキストでのみ使用されるクラスには、静的なネストされたクラス(技術的には内部クラスではありません)をよく使用します- Map.Entry はこの良い例です。 Mapと組み合わせてのみ使用されるため、Entryの定義をMapインターフェイスの一部とすることは、組織的に意味があります。
一般に、非静的メンバークラスやローカルクラスなど、他のタイプのネストされたクラスにはあまり使用しません。しかし、それらは時折便利になります。メンバークラスの正当な使用の良い例については、LinkedList.ListItrのソースコードを参照してください。これは、 LinkedList に対して ListIterator の実装を提供することを目的とするプライベート内部クラスです。これを行うには、LinkedList内のプライベートデータにアクセスできると便利です。トップレベルのクラスのみを使用してこれを実現するには、LinkedListでより多くのパブリックメソッドを公開して、ListIteratorがLinkedListの基になる実装に到達できるようにする必要があります。代わりに、内部クラスを使用することにより、LinkedListは実装をプライベートに保つことができます。
はい、内部クラスを使用する利点は、外部クラスのメンバーにアクセスできることです。あなたの場合、あなたのFooHelper
が他のクラスによって使用されないと思うなら、それを内部クラスにすることができます。
内部クラスのユーティリティを確認するには、AWTの例をご覧ください。匿名の内部クラスは、イベントハンドラーで広く使用されています。
Foo
のスコープとは何ですか? Foo
が ドメインモデルクラス 独自のライフサイクルで、helper
が一般的なサービスである場合、2つのオブジェクトが非常に異なるスコープ/ライフサイクルで混在しているようです。
通常、ドメインエンティティには、作成から永続性、GCまでの独自のライフサイクルがあります。一方、ヘルパーまたはサービスは静的またはより良いdynamicであり、ライフサイクルはアプリ全体に等しくなります。春豆。
ドメインエンティティにサービスの参照が含まれると、深刻な問題が発生する可能性があります。例えば。リポジトリのGet
を呼び出すたびに、このサービスの参照をドメインエンティティに挿入する必要があります。このパターンを避けることをお勧めします。
あなたにとってHelper
のインスタンスを作成するのは私には明らかではありません。
ヒルド、はい、多くの場合、内部クラスを使用するのが理にかなっています。
このように考えてください-内部クラスは外部クラスとともに存続し、消滅するため、外部クラスに特に必要な機能は内部クラスに追加できます。一般的な例は次のとおりです-ほとんどの場合のリスナー-KeyListeners、MouseListener、eventListenersのタイプ。
Javaのクラスを使用すると、特定の機能を使用できますが、個別の特殊な機能が必要な場合もありますが、設計しているクラスに密接に結び付ける必要もあります。
内部クラスには4つのタイプがあります。簡単なグーグル検索は、それらについてもっと知るのに役立ちます。
Oracle Docsの簡単な説明による
ネストされたクラスを使用する理由は次のとおりです。
1つの場所でのみ使用されるクラスを論理的にグループ化する方法ですクラスが他の1つのクラスにのみ有用である場合、そのクラスに組み込み、2つをまとめるのが論理的です。このような「ヘルパークラス」をネストすると、パッケージがより合理化されます。
カプセル化を増やします: 2つのトップレベルクラスAとBを考えます。Bは、そうでなければプライベートと宣言されるAのメンバーにアクセスする必要があります。クラスA内でクラスBを非表示にすることにより、Aのメンバーはプライベートと宣言され、Bはそれらにアクセスできます。さらに、B自体を外界から隠すことができます。
読みやすく保守しやすいコードにつながる可能性があります:最上位クラス内に小さなクラスをネストすると、コードが使用される場所の近くに配置されます。
ネストされたクラスを使用すると、1つの場所でのみ使用されるクラスを論理的にグループ化し、カプセル化の使用を増やし、読みやすく保守可能なコードを作成できます。ローカルクラス、匿名クラス。
http://docs.Oracle.com/javase/tutorial/Java/javaOO/whentouse.html
内部クラスを使用する場合