Javaに「サブクラスのみ」のアクセス修飾子がないのはなぜですか?


16

Javaには、メソッドに使用可能な4つのアクセス修飾子があります。

public -すべてのクラスがこのメソッドを使用できます。

protected -同じパッケージ内のクラスおよび任意のパッケージ内のサブクラスは、このメソッドを使用できます。

private -このクラスのみがこのメソッドを使用できます。

no modifier ( "package private")-同じパッケージ内のクラスのみがこのメソッドを使用できます。

よく起こるのは、すべてのサブクラスが使用できる便利なメソッドをスーパークラスに入れたいということです。しかし、他のクラスがこのメソッドにアクセスすることは意味がなく、ある意味ではカプセル化を破ります。

したがって、これらの便利なメソッドをスーパークラスpublicまたはで宣言するprotected必要があります。これにより、少なくともパッケージ内の他のすべてのクラスに公開されます。それらはサブクラスによってのみ使用されることを意図していますが。

subclasses-onlyJavaにアクセス修飾子がない理由はありますか?私にはとても奇妙に思えます。何か不足していますか?

また、subclasses-onlyアクセス修飾子は、サブクラスにのみ変数を公開する場合にも役立ちます。私にはこれがよく起こります。

回答:


10

保護された修飾子を使用し、親クラスとそのサブクラスのみが同じパッケージ内にあることを強制することにより、サブクラスのみの修飾子をエミュレートできるためです。

パッケージは結束の観点から大きなプロジェクトを整理するのに役立つだけでなく、同じパッケージ内のクラスがある程度のカップリングを持っている可能性があることも示しているため、実際に良い習慣です。


15
「そして、親クラスとそのサブクラスのみが同じパッケージ内にあることを強制する」-さて、それをどのように行うのでしょうか?!
JimmyB

1
そして、パッケージのみのアクセス修飾子を使用することはできません。そして、あなたは愚かな量のパッケージを必要とします。これは実用的な解決策ではありません。
user253751

13

Javaには元々そのような修飾子がありました。private protectedJava 1.0で作成されましたが、削除されました。

私はそれが余分な複雑さはコストに見合うものではないと判断したと思います。

すべての言語機能にはコストがかかります。新しいプログラマーに教えるには。ドキュメント内; コンパイラー、JVM、および開発ツールで実装する場合。プログラムの正確さについての推論; 将来の言語の進化を制限する。もっと。言語機能は互いに、潜在的にN 2の相互作用と相互作用します。

Javaプログラマーの何パーセントがJava言語仕様とVM仕様を読んだことがありますか?理解しやすく、信頼できるエンジニアリング製品のために、さらにシンプルな言語を主張しているのはわずかな割合だと思います

private protectedパッケージがモジュール化の主要な単位であるため、この機能の利点はわずかでした。


1
1.0の前にJavaバージョンがありましたか?
マークイースリー

1
@MarkYisri Javaには1995年にアルファ版とベータ版が公開されており、それらに対してかなりのコードが記述されていました。
デビッドモールズ

4

アクセス制御は、クラスのメソッドとプロパティについてクラスで作業している想像上の開発者との取材の結果と考えることができます...

YOU:xを実行したい場合、doXメソッドを呼び出します。DEV:詳細を教えてください。引数は何ですか?

これは公開されています...

あなた:doXの内部で私は電話します... DEV:おっと、情報が多すぎて、私はそれを気にしません。使い方を知りたいだけです。他に何か教えてください。

これはプライベートです...

あなた:サブクラス化するとき、doXとdoYを呼び出してdoItを呼び出します。

これは保護されています...

あなた:私は1時間で休暇に出かけます、私は次の6か月に行きます。ボスは、この子犬はあなたのものだと言います!またね DEV:まだ行かないで、すべて教えて...

これはパッケージです。

YOU:メソッドdoItWhenは、このクラスによってのみ呼び出され、10年間変更されていません。それ... DEV:おっ、50分になりました。次のプロパティ、およびより速く話す。

これはプライベートに保護されています...


3

これはすでに存在します。保護されています。

パッケージ内に存在するクラスを制御できます。パッケージに他のクラスがなく、指定された変数またはメソッドが保護されている場合、それは「サブクラスのみ」です。

ただし、パッケージ内に存在するクラスを制御できます。保護されたメソッドまたは変数を使用しないように選択できます。


3
特定の予約済みシステムパッケージとは別に、クラスを任意のパッケージに追加することはできません。クラスを追加するつもりがないあなたのパッケージであってもかまいませんか?
デビッドモールズ

@David IIRCはい。ただし、別のJARからパッケージフィールドにアクセスすることはできないため、同じパッケージに配置しても、別のJARにある場合はアクセスできません。ただし、同じJAR内で参照している場合は、はい、アクセスできますが、問題のJARを変更できる場合は、アクセス修飾子を簡単に変更できます。
ポケチュウ22

1
@ Pokechu22 その保護を得るには、JARを肯定的に封印する必要があると思いますが、良い点です。
デビッドモールズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.