クラスをとして定義できないのはなぜprotected
ですか?
できないことは知っていますが、なぜですか?いくつかの特定の理由があるはずです。
クラスをとして定義できないのはなぜprotected
ですか?
できないことは知っていますが、なぜですか?いくつかの特定の理由があるはずです。
回答:
それは意味がないからです。
保護されたクラスメンバー(メソッドまたは変数)は、サブクラスからもアクセスできることを除いて、package-private(デフォルトの可視性)と同じです。
Javaには「subpackage」や「package-inheritance」などの概念がないため、classprotectedまたはpackage-privateを宣言することも同じです。
ただし、ネストされたクラスと内部クラスを保護またはプライベートとして宣言できます。
open
、現在のパッケージの外部でサブクラス化を許可するKotlinの場合(protected
Javaでは、逆のデフォルトでそれを防ぐことが想像できます)。
ご存知のように、デフォルトはパッケージレベルのアクセス用で、protectedはパッケージレベルと非パッケージクラス用ですが、このクラスを拡張します(ここで注意すべき点は、クラスが表示されている場合にのみ拡張できることです!)。このようにしましょう:
このクラスが少数のクラスのみによってサブクラス化されることを制限する方法がないため(パッケージ内/パッケージ外の使用可能なすべてのクラスのうち、少数のクラスのみが継承するクラスを制限することはできません)、保護されたアクセス指定子は使用されません。トップレベルのクラス用。したがって、それは許可されていません。
@Nikita Rybakの答えには良い点がありますが、詳細が不足しています。自分自身を深く考えずに単純にアイデアを得ることができません。以下は私が考えたものであり、今では理由を完全に理解する必要があります。
4つのアクセス修飾子。第1レベルがパブリックで、第4レベルがプライベートであると想定します(このテーブルに順番に基づいています)。最初に知っておくべきことは、クラスをトップレベルでプライベートとして定義できない理由です。
したがって、「プライベートクラスfoo」(定義されたプライベートメンバー、つまりクラス自体がメンバーである)が許可する場合、外部(メンバーを含む)は何ですか?ファイルスコープ?いいえ、単一ファイル内の複数のクラスでさえ別々のクラスファイルにコンパイルされるため、ファイル外部は無意味です。つまり、アウターはパッケージです。ただし、第3レベルのデフォルトのアクセス修飾子は、すでに「package-private」を意味します。したがって、第4レベルのプライベートアクセス修飾子は使用/許可されません。
ただし、直接外部はパッケージではなくクラスであるため、ネストされたプライベートクラスは許可されます。例:
class PrivateNestedMain {
private static class Inner {
public static void main(String[] args) {
System.out.println("Hello from Inner!");
}
}
}
「保護されたクラスfoo」が許可した場合はどうなりますか?保護された主な特性はサブクラスであるため、outer(package)は(スコープまでですが、それでもオプションです)サブクラスのスタイル、つまりサブパッケージ、またはを提供する必要package A extends package B
がありますが、そのようなことはわかりません。したがって、protectedは、外部がパッケージである(つまり、そのようなサブパッケージのものがない)トップレベルで完全な可能性(メインスコープはサブクラス全体)を使用できませんが、protectedは、外部がクラスであるネストされたクラスで完全な可能性を使用できます(つまり、サブクラスにすることができます):
class ProtectedNestedMain {
protected static class Inner {
public static void main(String[] args) {
System.out.println("Hello from Inner!");
}
}
}
上記の「可能性を最大限に使用することはできません」の意味は、ことは、外サブクラス、ので、それに起因するが、単にサブクラス全体に到達できないと述べたことを注意実際に保護を許すことはできない、それはパッケージの複製ジョブを避けるために、好みの問題です-外部がサブクラス化できない場合はプライベート。以下を参照してください。
私の混乱は主にhttps://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.htmlの有名なテーブルが原因です:
第1レベル(パブリック)と第3レベル(パッケージ-プライベート)が許可されている場合、いったいどのようにして第2レベル(保護)の中間が許可されないのでしょうか。
パブリックサポートサブクラスは非常に誤解を招きやすいです。この表を読む正しい方法は
アウターにサブクラス機能がある場合は、パブリックサポートサブクラス。
同じ誤解を招くような適用がpackage-privateに適用され、package-privateはサブクラス(セル内のN)をサポートしていませんが、サブクラスの概念が外部に適用されることを意味しません。
つまり、外部でサブクラス機能が使用できない場合は、サブクラス列を無視する必要があります。
これでわかるように、protectedとpackage-privateの両方が同じレベル(YYN)になり、中間レベルが許可されない理由について混乱することはなくなりました。全体として、Javaは混乱を避けるために保護されたパッケージプライベートのみを選択し(これは選択の問題ですが、保護された主な特性はサブクラスであるため、パッケージプライベートが優れています)、その結果、トップレベルで許可されるアクセス修飾子は2つだけです。
トップレベル-パブリック、またはパッケージプライベート(明示的な修飾子なし)。
保護されたフィールドを定義すると、継承によってのみ(子クラス内のみ)、パッケージ内およびパッケージ外でそのフィールドにアクセスできるようになります。
したがって、クラスを保護することが許可されている場合、パッケージ内で非常に簡単にアクセスできますが、パッケージ外でそのクラスにアクセスするには、まず、このクラスが定義されているエンティティであるパッケージを拡張する必要があります。
また、パッケージは拡張できない(インポートできる)ため、保護されたクラスを定義すると、パッケージプライベートになります。これは、すでに実行できるデフォルトとして定義するのと同じです。したがって、クラスをプライベートに定義する利点はありません。それは物事を曖昧にするだけです。
詳細については、外部Javaクラスをプライベートまたは保護できない理由を参照してください。
Protectedはpublicとは異なります。Protectedは、パッケージレベルのアクセスに加えて、継承によってのみパッケージの外部にアクセスできます。パッケージの外部のクラスが他のパッケージからクラスを継承すると言う場合(INHERITANCEを使用して保護されたメソッドを使用)、このクラスBのメソッドにアクセスできます。には保護されたメソッドがありますが、このクラスから派生したサブクラス、つまりAは保護されたメソッドにアクセスできません。publicでは逆のことが起こります。
例:
package 2;
class B
{
protected void method1()
{
}
}
package 1;
import 2.B;
class A extends B
{
//can access protected method
}
class C extends A
{
//can't access the protected method
}
@ Akash5288からの回答は、私には意味がありませんでした。
すべてのクラスがサブクラス化を許可されている場合、それはパブリックアクセス指定子に似ています。
このクラスが少数のクラスのみによってサブクラス化されることを制限する方法がないため(パッケージ内/パッケージ外の使用可能なすべてのクラスのうち、少数のクラスのみが継承するクラスを制限することはできません)、保護されたアクセス指定子は使用されません。トップレベルのクラス用。したがって、それは許可されていません。
次に、保護されたメソッドと変数に同じロジックを適用できます。これらも「パブリックに似ています」。パッケージ外のすべてのクラスは、パブリッククラスを拡張し、その保護されたメソッドを使用できます。メソッドと変数を拡張クラスに制限しても問題ないのに、クラス全体を制限できないのはなぜですか?「パブリックに類似」は「パブリックと同じ」ではありません。私の解釈では、保護されたメソッドを許可することは問題ないので、保護されたクラスを許可することはまったく問題ありません。
「アクセス/表示できないクラスを拡張することはできません」という答えは、より論理的です。
この質問に意味があるのは、JVMはC(Sun JVM)とC ++(oracle JVM)で記述されているため、コンパイル中に、Javaファイルから.classファイルを作成し、Protectedキーワードでクラスを宣言する場合です。その場合、JVMはアクセスしません。
保護されたクラスがJVMによってアクセスされない理由の答えは、保護されたフィールドは同じパッケージ内または継承のみを介して異なるパッケージにアクセス可能であり、JVMはwillクラスを継承するように記述されていないためです。これがこの質問を満たすことを願っています:)
同様に、トップレベルのクラスをプライベートにすることはできません。以下の説明:
では、クラスprivateを定義するとどうなるでしょうか。そのクラスは、定義されているエンティティ(この場合はパッケージ)内でのみアクセスできます。
したがって、クラスへのプライベートアクセスを定義すると、デフォルトのキーワードがすでに行っているのと同じパッケージ内でアクセスできるようになります。したがって、クラスをプライベートに定義するメリットはなく、あいまいになるだけです。
保護とは、メンバーが同じパッケージ内の任意のクラスから、および別のパッケージ内にある場合でもサブクラスからアクセスできることを意味します。
例:
package a;
class parent{
protected void p();
}
package b;
import a.p;
class child extends parent{
//you can access method which is protected in the parent in the child
}
class another extends child {
//here you can not access the protected method
}