web-dev-qa-db-ja.com

javaのデフォルトのアクセス指定子と保護されたアクセス指定子の違い

Javaを学ぼうとしていましたが、アクセス指定子を調べたときに疑問がありました。何も指定されていない場合のデフォルトと保護されたアクセス指定子の違いは何ですか?

21
abhips

protected指定子を使用すると、問題のクラスのすべてのサブクラス(それらがどのパッケージに属しているか)、および同じパッケージ内の他のコードからアクセスできます。デフォルトの指定子は、同じパッケージ内の他のコードによるアクセスを許可しますが、異なるパッケージにあるサブクラス内のコードによるアクセスは許可しません。 Java言語仕様セクション6.6 を参照してください。

編集:MichaelSchmeißerのリクエストにより(他の人がコメントを読んだり、リンクをたどってこれを見つける必要はありません):インターフェイスのすべてのメンバーは暗黙的に公開されています。実際、public以外のインターフェイスメンバにアクセス指定子を指定することは、コンパイル時エラーです(ただし、パブリックアクセスのデフォルトはすべてアクセス指定子ではありません)。クラスメンバーのJLSからのルールの完全なセットは次のとおりです(パッケージ、トップレベルのクラスとインターフェイス、および配列のルールについては上記のリンクを参照してください)。

参照(クラス、インターフェイス、または配列)型のメンバー(クラス、インターフェイス、フィールド、またはメソッド)またはクラス型のコンストラクターにアクセスできるのは、その型がアクセス可能で、メンバーまたはコンストラクターがアクセスを許可するように宣言されている場合のみです:

  • メンバーまたはコンストラクターがパブリックと宣言されている場合、アクセスが許可されます。

  • インターフェイスのすべてのメンバーは暗黙的にパブリックです。

  • それ以外の場合、メンバーまたはコンストラクターが保護されていると宣言されている場合、次のいずれかが真である場合にのみアクセスが許可されます。

  • メンバーまたはコンストラクターへのアクセスは、保護されたメンバーまたはコンストラクターが宣言されているクラスを含むパッケージ内から発生します。

  • §6.6.2 で説明されているように、アクセスは正しいです。 (この句は、派生クラスがスーパークラスの保護されたメンバーにアクセスすることを許可する規則を指します。§6.6.2開始:」オブジェクトの保護されたメンバーまたはコンストラクターは、パッケージの外部からアクセスできますこれは、そのオブジェクトの実装を担当するコードによってのみ宣言されます。」その後、それについて詳しく説明します。)

  • それ以外の場合、メンバーまたはコンストラクターがprivateとして宣言されている場合、メンバーまたはコンストラクターの宣言を囲む最上位クラス( §7.6 )の本体内で発生する場合にのみアクセスが許可されます。

  • それ以外の場合は、デフォルトのアクセスがあり、型が宣言されているパッケージ内からアクセスが発生した場合にのみ許可されます。

34
Ted Hopp

これは、Java tutorial に役立つかもしれません。

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
37
Coding Master

保護されたアクセス指定子-保護されたデータにアクセスするには2つの方法があります

  1. 保護されたデータメンバー、クラスの保護されたメソッドは、他のクラスに存在する場合、他のクラスに表示されます。 同じパッケージ

  2. を使用して 継承

    そのクラスを継承することで、そのクラスの保護されたデータを使用できることを意味します。

デフォルトのアクセス指定子-デフォルトのデータにアクセスする唯一の方法

デフォルトは、デフォルトのデータメンバーを持つクラスを拡張した後でも、パッケージレベルのみにアクセスを制限します。アクセスできません。

ProvideProtectedのint xのデフォルトのremove protectedキーワードを確認するには、コンパイル時エラーが生成されます。

        1. SuperClass

        package nee.superclass;

        public class ProvideProtected {
            protected int x=800;

        }

        2.Subclass


        package nee.subclass;

        import nee.superclass.*;

        public class AccessProtected extends ProvideProtected 

        {   
        public void accessProtected()
            {
                System.out.println(x);
            }

            public static void main(String[] args) {
                AccessProtected obj=new AccessProtected();
                obj.accessProtected();

            }

        }
3
Neelam Chahal

Protected Access Modifier:-protectedとマークされたものはすべて同じパッケージ内で表示され、サブクラスでも表示されます。

デフォルトのアクセス:-デフォルトはキーワードではありません。アクセス修飾子が指定されていない場合に適用されます。基本的にはパッケージレベルの修飾子です。このようなアクセス権を持つものはすべて、同じパッケージに表示されます。

例の助けを借りて、違いをよりよく説明できるようになりました

パッケージp1

_public class A
{

protected void fn()
{

}

} 
_

パッケージp1

_public class B
{

A a1 = new A();

a1.fn();// fn() is visible inside the same package

}

}
_

今、私たちは別のパッケージのサブクラスに来ます

パッケージp2

_public class D extends A

{

void test()

{

A a1 = new new A();

    //a1.fn() -->  would give compilation error
fn();

super.fn();

}

}
_

fn(), super.fn()はエラーを出しません。

そのため、スーパークラスの参照を介してメソッドを呼び出すことができないサブクラスに違いがあります。直接呼び出すか、superを使用できます。

super.fn()は非静的メソッドの一部でなければならないことに注意してください。

2
Akshat Bansal