クラスを保護対象として定義できないのはなぜですか?


89

クラスをとして定義できないのはなぜprotectedですか?

できないことは知っていますが、なぜですか?いくつかの特定の理由があるはずです。


3
それは何を考えません、あなたが保護されたクラスを宣言した場合は?

1
私はこれがあなたが探しているものだと思います:stackoverflow.com/questions/2534733/java-protected-classes :D
dewijones92 2013年

2
なぜ外部クラスを保護できないのかを言いましょう。内部クラスを保護できます。
番号945 2018

回答:


101

それは意味がないからです。

保護されたクラスメンバー(メソッドまたは変数)は、サブクラスからもアクセスできることを除いて、package-private(デフォルトの可視性)と同じです。
Javaには「subpackage」や「package-inheritance」などの概念がないため、classprotectedまたはpackage-privateを宣言することも同じです。

ただし、ネストされたクラスと内部クラスを保護またはプライベートとして宣言できます。


> Javaには「subpackage」や「package-inheritance」などの概念がないため、classprotectedまたはpackage-privateを宣言することも同じです。保護されたクラスがpackage-privateと同じ可視性を持つのはなぜですか?パブリックと同じではないですか?ありがとう。
yaromir 2014

@Nikita Ryback subPackageまたはpackage-inheritanceとは何ですか?保護がトップレベルクラスで使用される理由はまだわかりません。例を挙げて説明すると、すばらしいでしょう。
App Kart

クラスメンバーを保護されていると宣言すると、その可視性は同じパッケージ(パッケージアクセスと呼ばれる)とサブクラスのクラスになります。他のパッケージの外部クラスからアクセスしようとすると、この保護されたメソッドメンバーは表示されません。
kelgwiin 2015年

@kelgwiinクラスのアクセス修飾子とメンバーのアクセス修飾子を混在させないでください。2つが違うからです。クラスはそれ自体をパブリックまたはデフォルトとして変更できますが、メンバーはパブリック、プライベート、保護、およびデフォルトとして変更できます。
sharhp 2017

2
「それは意味をなさないので」-それはかなり大胆な声明です。Javaでは定義されていませんが、同様のもの存在します。たとえばopen、現在のパッケージの外部でサブクラス化を許可するKotlinの場合(protectedJavaでは、逆のデフォルトでそれを防ぐことが想像できます)。
ラファエル

41

ご存知のように、デフォルトはパッケージレベルのアクセス用で、protectedはパッケージレベルと非パッケージクラス用ですが、このクラスを拡張します(ここで注意すべき点は、クラスが表示されている場合にのみ拡張できることです!)。このようにしましょう:

  • 保護された最上位クラスは、そのパッケージ内のクラスに表示されます。
  • パッケージ(サブクラス)の外部に表示するのは少し混乱し、注意が必要です。どのクラスに保護されたクラスの継承を許可する必要がありますか?
  • すべてのクラスがサブクラス化を許可されている場合、それはパブリックアクセス指定子に似ています。
  • ない場合は、デフォルトと同様です。

このクラスが少数のクラスのみによってサブクラス化されることを制限する方法がないため(パッケージ内/パッケージ外の使用可能なすべてのクラスのうち、少数のクラスのみが継承するクラスを制限することはできません)、保護されたアクセス指定子は使用されません。トップレベルのクラス用。したがって、それは許可されていません。


3
「保護されたクラスをパッケージ(サブクラス)の外部に表示するのは少し混乱し、注意が必要です。どのクラスに保護されたクラスの継承を許可する必要がありますか?すべてのクラスにサブクラスを許可する場合は、パブリックアクセス指定子に似ています。」保護されたクラスが意味をなさない理由に関する問題を理解するのに本当に役立ちました:)
user1338998 2014年


3

@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つだけです。

トップレベル-パブリック、またはパッケージプライベート(明示的な修飾子なし)。


3

保護されたフィールドを定義すると、継承によってのみ(子クラス内のみ)、パッケージ内およびパッケージ外でそのフィールドにアクセスできるようになります。

したがって、クラスを保護することが許可されている場合、パッケージ内で非常に簡単にアクセスできますが、パッケージ外でそのクラスにアクセスするには、まず、このクラスが定義されているエンティティであるパッケージを拡張する必要があります。

また、パッケージは拡張できない(インポートできる)ため、保護されたクラスを定義すると、パッケージプライベートになります。これは、すでに実行できるデフォルトとして定義するのと同じです。したがって、クラスをプライベートに定義する利点はありません。それは物事を曖昧にするだけです。

詳細については、外部Javaクラスをプライベートまたは保護できない理由を参照してください。


3
所属を開示し、投稿を通じてサイトを宣伝する方法としてサイトを使用しないでください。良い答えを書くにはどうすればよいですか?を参照してください

1

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
}

0

「保護された」の動作=「デフォルト」の動作+「任意のパッケージの任意のサブクラスで使用する」。

とにかく、クラスのデフォルトのアクセス修飾子がありますが、保護されたアクセス修飾子から得られる利点は次のとおりです。-サブクラス化を通じて任意のパッケージで使用する。ただし、サブクラスの場合、親の「保護された」クラスの可視性は非公開になります。そのため、アクセスできません。基本的に、保護されたトップレベルクラスがある場合、外部クラスはそれをサブクラス化してアクセスすることはできません。したがって、トップレベルのクラスに対して保護されていることは無意味です。


0

保護:パッケージレベル*にのみ表示されます。

クラスは保護れて定義されています--->外部パッケージから拡張することはできません(表示れません)。

また、拡張できない場合は、保護されたままにしておくことは意味がありません。これは、許可されるデフォルトのアクセスになるためです

同じことがプライベート定義クラスにも当てはまります。

注:ネストされたクラスまたは内部クラスは、保護またはプライベートとして定義できます。

*保護されたキーワードを調べてください。この答えのために私はそれを簡潔にしました。


0

@ Akash5288からの回答は、私には意味がありませんでした。

すべてのクラスがサブクラス化を許可されている場合、それはパブリックアクセス指定子に似ています。

このクラスが少数のクラスのみによってサブクラス化されることを制限する方法がないため(パッケージ内/パッケージ外の使用可能なすべてのクラスのうち、少数のクラスのみが継承するクラスを制限することはできません)、保護されたアクセス指定子は使用されません。トップレベルのクラス用。したがって、それは許可されていません。

次に、保護されたメソッドと変数に同じロジックを適用できます。これらも「パブリックに似ています」。パッケージ外のすべてのクラスは、パブリッククラスを拡張し、その保護されたメソッドを使用できます。メソッドと変数を拡張クラスに制限しても問題ないのに、クラス全体を制限できないのはなぜですか?「パブリックに類似」は「パブリックと同じ」ではありません。私の解釈では、保護されたメソッドを許可することは問題ないので、保護されたクラスを許可することはまったく問題ありません。

「アクセス/表示できないクラスを拡張することはできません」という答えは、より論理的です。


0

この質問に意味があるのは、JVMはC(Sun JVM)とC ++(oracle JVM)で記述されているため、コンパイル中に、Javaファイルから.classファイルを作成し、Protectedキーワードでクラスを宣言する場合です。その場合、JVMはアクセスしません。

保護されたクラスがJVMによってアクセスされない理由の答えは、保護されたフィールドは同じパッケージ内または継承のみを介して異なるパッケージにアクセス可能であり、JVMはwillクラスを継承するように記述されていないためです。これがこの質問を満たすことを願っています:)

同様に、トップレベルのクラスをプライベートにすることはできません。以下の説明:

では、クラスprivateを定義するとどうなるでしょうか。そのクラスは、定義されているエンティティ(この場合はパッケージ)内でのみアクセスできます。

したがって、クラスへのプライベートアクセスを定義すると、デフォルトのキーワードがすでに行っているのと同じパッケージ内でアクセスできるようになります。したがって、クラスをプライベートに定義するメリットはなく、あいまいになるだけです。


0

保護とは、メンバーが同じパッケージ内の任意のクラスから、および別のパッケージ内にある場合でもサブクラスからアクセスできることを意味します。

例:

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 
}

0

外部クラスがprotectedによって宣言されている場合、クラスは同じパッケージとそのサブクラスからのみアクセスできるが、異なるパッケージからのみアクセスできるようにする必要があると思います。ただし、「class Dog extends Animal」と書くと、保護された「Animal」はそのサブクラスからしかアクセスできないため、保護されたクラスのサブクラスを作成することはできません。明らかに、「Dog」は「Animal」サブクラスではありません。 。

したがって、保護された外部クラスは(デフォルトの)外部クラスと同じです!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.