Javaで、「保護された」修飾子を持つメンバーが同じクラスとサブクラスだけでなく、同じパッケージ内のすべての人からもアクセスできる理由は何ですか?
実際のアプリケーション(テストなど)ではなく、言語設計の理由について疑問に思っています。
Javaで、「保護された」修飾子を持つメンバーが同じクラスとサブクラスだけでなく、同じパッケージ内のすべての人からもアクセスできる理由は何ですか?
実際のアプリケーション(テストなど)ではなく、言語設計の理由について疑問に思っています。
この設計は、パッケージが適切なユニットであり、内部的に一貫性のある1つのチームによって保守およびリリースされるという考えに基づいています。継承関係は、誰がいつ何を維持および解放するかとはあまり関係がありません。
修飾子については、http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.htmlで詳しく説明されています。そこからこの図が見えます。
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
このことから、設計上の決定の理由は明らかです。それは、優れた対称行列を持つことです。
Java 1.0では、5番目のアクセス修飾子がありましたprivate protected
。これにprotected
はデフォルトのアクセスがありませんでした。どうやらそれは実際に正しく動作することはなく、1.1で削除されました。したがって、クレームprotected
は、全順序付けの方法で定義されているように見えますが、偽物のように見えます。(編集: 1.1で5番目のアクセス修飾子が削除された理由の少なくとも1つは、全体的な順序の欠如がオーバーロード選択ルールに干渉したことであるようです。)module
Java 7のアクセス修飾子には、この領域でいくつかの設計上の質問があります。 。
メンバーのデフォルトのアクセス修飾子を「パッケージプライベート」にするのは良い考えだと考えられていたprotected
ので、少なくともこのレベルのアクセスが必要であると考えられます。私のお金のために、protected
その言語ではまったくお金を払っていません。
基本的には、API 制御ユニットとしてのパッケージのビューに関係しています (したがって、ドメイン名でパッケージを開始することをお勧めします - グローバルな一意性が保証されています)。 . protected が package-private の増加ではなく、異なるタイプの可視性である場合、必要に応じて 2 つのタイプの可視性を組み合わせる何らかの方法が必要になります。
プログレッシブ レベルのアクセス、プライベート、パッケージ、プロテクト、パブリックを考えると、保護されてからパッケージになると、同じパッケージの他のメンバーを許可するためにサブクラスのアクセスを許可する必要があるため、不必要に制限されます。それでも、直観的には、同じパッケージ内の他のクラスは、「そこにある」他のクラスよりも信頼できるはずです。そのため、保護されているのは、パッケージとパブリックの間であり、アクセスをより広く公開できます。
基本的な理由は、同じパッケージ内のクラス間に基本レベルの「信頼」があるという直感に依存していると思います。ほとんどの場合、パッケージは 1 人のエンジニアまたはチームの責任となるため、一貫した設計の調和が必要です。
Java 自体は、その設計原則に従っています。サブクラスのパブリック メソッドのスコープを縮小/縮小しようとするとどうなりますか? エラーが発生します。Java スコープ修飾子のレベルは次のとおりです。 private < (デフォルト) < protected < public
パッケージ内のすべてのクラスは、連携して機能するため、フレンドリーである必要があります。メンバーをパッケージで使用できるようにするために、メンバーは既定のスコープで定義されます。
サブクラスは、再びスコープ レベルに従って、パッケージの外部に存在する場合があります。private < (デフォルト) < protected < public - スコープを絞り込むことはできません。Protected はデフォルトよりもスコープが広いため、Java は独自のガイドラインに矛盾しません。したがって、保護されたメンバーはデフォルトのスコープで使用できます。また、クラス < パッケージ < プロジェクト。
モディファイヤは可視性だけにとどまらず、継承、構造も同時に動いているので画像にも追加してください。これが true の場合: private < protected < (デフォルト) < public. 次に、すべてのサブクラスが同じパッケージに存在する必要があります。なぜ継承する必要があるのか 、パッケージレベルで適用可能なデフォルトスコープがあるため、すべてにアクセスできます。デフォルトのスコープはその価値を失い、継承も失われます。