デフォルトの修飾子はパッケージへのアクセスを許可するがサブクラスへのアクセスは許可せず、protectedは両方へのアクセスを許可するため、Java アクセス修飾子は暗黙的にサブクラスよりもパッケージへのアクセス優先度を与えますが、サブクラスへのアクセスを許可するがパッケージへのアクセスを許可しない修飾子はありません。これは私にとって常に奇妙に感じられます。なぜなら、私は自然に、サブクラスを親に「近い」と考える傾向があり (結局のところ、サブクラスが独自の変数であるため)、同じパッケージ内のクラスであることに気付くことがよくあります。パッケージではなく、サブの修飾子が必要です。これはおそらく、パッケージを「間違った」方法で使用していることを意味しますが、誰かがこの決定の背後にあるロジックを説明できますか?
2 に答える
修飾子を使用しているときはprotected、クラスへの無制限のアクセスを許可しています。クラスがサブクラス化に不適切であっても、いつでも拡張することができます。修飾子を使用する場合protected、基本的には、そのクラスは (近い将来) 常にサブクラス化に適していると言えます。これはあなたが望むものではないかもしれません。たとえば、プロジェクトのために数回拡張されるはずのクラスがあり、その後はそれ以上拡張されない場合などです。
修飾子 (default-access/package-private) がない場合は、クラスへのアクセスが制限されています。誰も、あなたでさえも、パッケージの外部でそのクラスにアクセスすることはできません。これは、クラスがプロジェクトに固有であり、他の任意のプロジェクトのためにそれを拡張する上記のケースのようなことをしている場合に必要なものです。不適切でしょう。以下は、最高のアクセスから最低のアクセスへのリストです。
public: 誰でも、すべてに無制限にアクセスprotected: 無制限のアクセスですが、より制限されています- default-access : 有限量の他のクラスへの制限付きアクセス
private: 非常に制限されたアクセス: いかなるものからもアクセスできません
と default-accessの間に 5 番目のアクセス修飾子をprotected配置して、それを拡張したいすべてのクラスがアクセスできるようにしますが、拡張したくない場合はアクセスできないようにすることは、フォームに既に存在するため冗長です。のpublic abstract。
アプリケーションはモジュール化する必要があります。これは事実です。また、モジュールには相互に通信する手段が必要です。これら 2 つのユースケースは、デフォルトおよび保護されたパッケージの目的です。
通常、ビルドしているモジュールに関連するファイルは同じパッケージにあります。例えば:
--my_module
|-- MainModuleClass
|-- HelperA
|-- HelperB
この場合、MainModuleClass通常はタイプのフィールドがありHelperA、HelperBモジュールを開発するチームは 3 つのクラスすべてを作成しました。したがって、「彼らは何をしているかを知っています」。また、これら 3 つのクラスはすべて、関連性の高い役割を担っています。これらはモジュールのコアを構成します。これら 2 つの理由から、"パッケージ アクセス" を使用するのに最適な場所です。お互いのクラスのメンバーに安全にアクセスできるからです。
さらに、このモジュールのテストは、モジュール自体と同じパッケージにあります (ディレクトリは異なりますが、問題ありません)。したがって、モジュールの作成者は、モジュール クラスの「デフォルト」アクセス フィールドにアクセスして、内部状態を読み取り、内部動作が正しいかどうかを確認できます。
ここで、他の開発者がこれらのクラスの 1 つを拡張して何らかの機能を追加することを決定した場合、そのプログラマーは定義上、「他の」プログラマーです。彼はコードも、元のコンポーネントを作成した最初のチームも知りません。したがって、一部のフィールドは「保護」とマークされており、コードを拡張して安全に拡張したい「部外者」にのみアクセスを許可します。
要約する:
- モジュールを構築していて、一部のフィールドをモジュール内のクラスだけが使用できるようにしたい場合は、デフォルトの可視性が最適です。
- 一部のフィールドが拡張されたり、モジュールを再利用したい他のチームによって使用されたりする場合は、それらのフィールドを保護する必要があります。