web-dev-qa-db-ja.com

Javaにおけるpublic、protected、package-private、およびprivateの違いは何ですか?

Javaでは、publicname__とprotectedname__を作成して継承を処理する際に、それぞれのアクセス修飾子、つまりデフォルト(package private)、privatename__、classname__、およびinterfacename__をいつ使用するかについて明確な規則がありますか?

2830
intrepion

公式チュートリアル はあなたに役立つかもしれません。

│クラス│パッケージ│サブクラス│サブクラス│ワールド
│││(同一pkg)│(diff pkg)│
──────────── ┼───────┼───────────────────────────────── 
] public│+│+│+│+│+ 
────────────────────────────── ┼─────────────────────────────
保護│+│+│+│+│
────────────────────────────────────────── ───┼────────
修飾子なし│+│+│+││
─────────── ┼───────┼───────────────────────────────── 
プライベート│+│││[
] 
 +:アクセス可能空白:アクセス不可
5155
user13673

(警告:私はJavaプログラマーではない、私はPerlプログラマーです。Perlには正式な保護がないため、おそらく問題をよく理解しているのでしょう:)

非公開

あなたが思うように、それが宣言されている class だけがそれを見ることができます。

パッケージプライベート

それが宣言されている パッケージ によってのみ表示および使用できます。これはJavaのデフォルトです(これは間違いと思われます)。

保護されています

Package Private +は、サブクラスまたはパッケージメンバーから見ることができます。

パブリック

誰でも見ることができます。

公開済み

私が管理しているコードの外側に表示されます。 (Javaの構文ではありませんが、この説明にとって重要です)。

C++は "friend"と呼ばれる追加のレベルを定義しています。

いつ何を使うべきですか?全体のアイデアは、情報を隠すためのカプセル化です。できる限り、ユーザーから何かが行われる方法の詳細を隠したいです。どうして?それなら、後でそれらを変更して、誰かのコードを壊さないようにすることができます。これにより、見直したばかりのコードを誰かが使用していることを心配することなく、バグを最適化、リファクタリング、再設計、および修正することができます。

そのため、経験則では、必要な範囲で物を見えるようにするだけです。プライベートから始めて、必要に応じてより多くの可視性を追加してください。ユーザーが知ることが絶対に必要であることを公にするだけで、あなたが公にするあらゆる詳細はシステムを再設計するあなたの能力を痙攣させます。

内部を公開してオーバーライドできるようにするのではなく、ユーザーが動作をカスタマイズできるようにしたい場合は、それらの機能をオブジェクトに置き換えてそのインターフェイスを公開することをお勧めします。そのように彼らは単に新しいオブジェクトを差し込むことができます。たとえば、CDプレーヤーを作成していて、「このCDに関する情報を探す」ビットをカスタマイズ可能にするのではなく、それらのメソッドを公開するのではなく、すべての機能を独自のオブジェクトに置き、オブジェクトの取得/設定メソッドを公開する。このように、あなたの内臓を露出させることにけんかであることは、良い構成と懸念の分離を促進します

個人的には、「プライベート」と「パブリック」だけを使います。多くのOO言語がそれを持っています。 「保護された」は便利かもしれませんが、それは本当にカンニングです。インターフェースが非公開になると、それはあなたのコントロールの範囲外になり、用途を見つけるために他の人のコードを調べに行かなければなりません。

これが「発行された」という概念が出てくるところです。インターフェースを変更する(それをリファクタリングする)には、それを使用しているすべてのコードを見つけてそれを変更することも必要です。インターフェイスがプライベートの場合は、問題ありません。それが保護されているなら、あなたはすべてのあなたのサブクラスを見つけに行かなければなりません。一般公開の場合は、自分のコードを使用しているすべてのコードを探しに行く必要があります。時にはこれが可能です、例えばあなたが社内使用のみを目的としたコーポレートコードを扱っているのであれば、インターフェースがパブリックであるかどうかは関係ありません。コーポレートリポジトリからすべてのコードを取得できます。しかし、インターフェースが「公開」されている場合、それを使用しているコードがあなたのコントロールの外にある場合は、あなたは詐欺されています。あなたはそのインターフェースをサポートするか、コードを破る危険を冒さなければなりません。保護されたインターフェースでさえ公開されていると考えることができます(それが私がprotectedに悩まない理由です)。

多くの言語では、public/protected/privateの階層的な性質が制限されすぎており、現実と一致していないと考えられています。そのために トレイトクラス の概念がありますが、それは別のショーです。

422
Schwern

これはテーブルのより良いバージョンです。 (モジュールの欄がある将来の証明)

Java Access Modifiers

説明

  • private member(i)は、宣言されたのと同じクラス内でonlyアクセス可能です。

  • アクセス修飾子 j)を持たないメンバーは、同じパッケージ内のクラス内でのみアクセス可能です。

  • protected member(k)は、他のパッケージのサブクラス内の同じパッケージand内のすべてのクラス内でアクセス可能です。

  • public member(l)はすべてのクラスからアクセスできます(宣言されているパッケージをエクスポートしない module に存在しない場合)。


どのモディファイアを選ぶ?

アクセス修飾子は、誤ってカプセル化を破るのを防ぐのに役立つツールです。(*)。メンバーをクラス、パッケージ、クラス階層の内部にあるものにするのか、まったく内部に属さないのかを自問し、それに応じてアクセスレベルを選択します。

例:

  • フィールドlong internalCounterは変更可能なので実装の詳細なのでおそらくプライベートにすべきです。
  • (同じパッケージ内の)ファクトリクラス内でのみインスタンス化されるべきクラスは、パッケージ外部から直接呼び出すことは不可能なはずなので、パッケージ制限付きのコンストラクタを持つべきです。
  • レンダリングの直前に呼び出され、サブクラスでフックとして使用される内部のvoid beforeRender()メソッドは保護されるべきです。
  • GUIコードから呼び出されるvoid saveGame(File dst)メソッドはpublicであるべきです。

(*) カプセル化とは何ですか?

354
aioobe
                | highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
 \ xCanBeSeenBy | this          | any class | this subclass | any
  \__________   | class         | in same   | in another    | class
             \  | nonsubbed     | package   | package       |    
Modifier of x \ |               |           |               |       
————————————————*———————————————+———————————+———————————————+———————
public          |       ✔       |     ✔     |       ✔       |   ✔   
————————————————+———————————————+———————————+———————————————+———————
protected       |       ✔       |     ✔     |       ✔       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
package-private |               |           |               |
(no modifier)   |       ✔       |     ✔     |       ✘       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
private         |       ✔       |     ✘     |       ✘       |   ✘    
181
Abdull

簡単なルールすべてプライベートを宣言することから始めます。そして、ニーズが発生しデザインがそれを正当化するにつれて公衆に向かって進歩する。

あなたが表現の選択または抽象化の選択を公開しているかどうか、メンバーを公開するときに自分自身に尋ねます。 1つ目は、観察可能な振る舞いではなく実際の表現にあまりにも多くの依存関係が生じるため、避けたいものです。

原則として、サブクラス化によってメソッド実装をオーバーライドしないようにします。論理を台無しにするのは簡単すぎる。オーバーライドする予定がある場合は、抽象保護メソッドを宣言します。

また、オーバーライドするときに@Overrideアノテーションを使用して、リファクタリングしたときに壊れないようにします。

148
John Nilsson

実際には、単純なグリッド表示よりも少し複雑です。グリッドは、アクセスが許可されているかどうかを示しますが、アクセスを正確に構成するものは何ですか?また、アクセスレベルは入れ子になったクラスや継承と複雑な方法で相互作用します。

「デフォルト」アクセス(キーワードの不在によって指定される)は、 package-private とも呼ばれます。例外:インタフェースでは、修飾子はパブリックアクセスを意味しません。 public以外の修飾子は禁止されています。列挙型定数は常にパブリックです。

概要

このアクセス指定子を持つメンバーへのアクセスは許可されていますか?

  • メンバがprivate:メンバが呼び出しコードと同じクラス内で定義されている場合のみ。
  • メンバーはパッケージ非公開です:呼び出し側のコードがメンバーをすぐに囲むパッケージ内にある場合のみです。
  • Memberがprotected:同じパッケージ、またはmemberが呼び出しコードを含むクラスのスーパークラスに定義されている場合.
  • メンバーはpublic:はい。

どのアクセス指定子が適用されるのか

ローカル変数と仮パラメータはアクセス指定子を取ることができません。有効範囲の規則に従って、それらは本質的に外部からアクセスできないので、それらは事実上非公開です。

最上位スコープのクラスには、publicとpackage-privateのみが許可されています。この設計上の選択は、おそらくprotectedprivateがパッケージレベルで冗長になるためです(パッケージの継承はありません)。

すべてのアクセス指定子はクラスメンバ(コンストラクタ、メソッド、静的メンバ関数、ネストクラス)で使用できます。

関連: Javaクラスのアクセシビリティ

注文

アクセス指定子は厳密に順序付けることができます

公開>保護>パッケージプライベート>プライベート

publicが最も多くのアクセスを提供し、privateが最も少ないアクセスを提供することを意味します。非公開メンバーで可能な参照はすべて、パッケージ非公開メンバーにも有効です。パッケージプライベートメンバーへの参照は、保護されたメンバーに対しても有効です。 (同じパッケージ内の他のクラスへの保護されたメンバーへのアクセス権の付与は間違いと見なされました。)

ノート

  • クラスのメソッドareは、同じクラスの他のオブジェクトのプライベートメンバにアクセスすることを許可されています。 より正確には、クラスCのメソッドは、Cの任意のサブクラスのオブジェクト上のCのプライベートメンバにアクセスできます。Javaは、インスタンスによるアクセスの制限をサポートしていません。クラスによってのみです。 (private[this]を使ってそれをサポートしているScalaと比較してください。)
  • オブジェクトを構築するにはコンストラクタにアクセスする必要があります。したがって、すべてのコンストラクタが非公開の場合、クラスはクラス内に存在するコード(通常は静的ファクトリメソッドまたは静的変数初期化子)によってのみ構築できます。パッケージプライベートまたは保護されたコンストラクタについても同様です。
    • プライベートコンストラクタのみを持つということは、Javaがスーパークラスコンストラクタを暗黙的または明示的に呼び出すためにサブクラスのコンストラクタを必要とするため、クラスを外部でサブクラス化することもできないということです。 (ただし、サブクラス化した入れ子クラスを含めることはできます。)

内部クラス

内部クラスのようなネストスコープも考慮する必要があります。複雑さの例としては、内部クラスにメンバーがあり、それ自体がアクセス修飾子を取ることができることが挙げられます。それで、あなたは公の会員と共に私的な内部クラスを持つことができます。メンバーにアクセスできますか?一般的な規則は、スコープを見て、各レベルにアクセスできるかどうかを確認するために再帰的に考えることです。

しかし、これは非常に複雑で、詳細については Java言語仕様を参照してください 。 (はい、過去にコンパイラのバグがありました。)

これらがどのように相互作用するのかについては、この例を検討してください。プライベートな内部クラスを「リーク」することは可能です。これは通常警告です。

class Test {
    public static void main(final String ... args) {
        System.out.println(Example.leakPrivateClass()); // OK
        Example.leakPrivateClass().secretMethod(); // error
    }
}

class Example {
    private static class NestedClass {
        public void secretMethod() {
            System.out.println("Hello");
        }
    }
    public static NestedClass leakPrivateClass() {
        return new NestedClass();
    }
}

コンパイラ出力:

Test.Java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
        Example.leakPrivateClass().secretMethod(); // error
                                  ^
1 error

いくつかの関連質問:

103

経験則として:

  • private:クラススコープ.
  • default(またはpackage-private):パッケージスコープ。
  • protectedpackage scope + child(packageのようですが、異なるパッケージからサブクラス化することができます)。保護された修飾子は常に「親子」関係を保ちます。
  • public:至る所に。

その結果、アクセス権を3つの権利に分割すると、

  • (D)irect (同じクラス内のメソッドから呼び出す)。
  • (R)eference (クラスへの参照を使って、あるいは "ドット"構文を使ってメソッドを呼び出す).
  • (I)nheritance (サブクラス化による).

それから我々はこの単純なテーブルを持っています:

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+
77
nxhoaf

とても短い

  • public:どこからでもアクセス可能.
  • protected:同じパッケージのクラスおよび任意のパッケージに存在するサブクラスによってアクセス可能です。
  • デフォルト(修飾子を指定しない):同じパッケージのクラスからアクセス可能.
  • private:同じクラス内でのみアクセス可能.
48
Ravi

Javaで最も誤解されていたアクセス修飾子はprotectedです。サブクラスがそれを見ることができるという1つの例外を除いて、これはデフォルトの修飾子に似ていることがわかっています。しかし、どうですか?これが混乱を明確にするための例です。

  • 2つのクラスがあるとします。 FatherSon、それぞれ独自のパッケージに入っています。

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
    
  • 保護されたメソッドfoo()Fatherに追加しましょう。

    package fatherpackage;
    
    public class Father
    {
        protected void foo(){}
    }
    
  • メソッドfoo()は4つのコンテキストで呼び出すことができます。

    1. foo()が定義されているのと同じパッケージ内にあるクラス内(fatherpackage):

      package fatherpackage;
      
      public class SomeClass
      {
          public void someMethod(Father f, Son s)
          {
              f.foo();
              s.foo();
          }
      }
      
    2. サブクラス内で、現在のインスタンス上でthisまたはsuperを介して:

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
      
    3. 型が同じクラスの参照では、次のようになります。

      package fatherpackage;
      
      public class Father
      {
          public void fatherMethod(Father f)
          {
              f.foo(); // valid even if foo() is private
          }
      }
      
      -------------------------------------------
      
      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Son s)
          {
              s.foo();
          }
      }
      
    4. 型が親クラスで、それが inside である参照では、foo()が定義されているパッケージ(fatherpackage)[これはコンテキスト番号の内側に含めることができます。 1]:

      package fatherpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo();
          }
      }
      
  • 以下の状況は無効です。

    1. 型が親クラスで、それが outside foo()が定義されているパッケージ(fatherpackage)の参照

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo(); // compilation error
          }
      }
      
    2. サブクラスのパッケージ内の非サブクラス(サブクラスは保護されたメンバーをその親から継承し、それらを非サブクラスに対してプライベートにします):

      package sonpackage;
      
      public class SomeClass
      {
          public void someMethod(Son s) throws Exception
          {
              s.foo(); // compilation error
          }
      }
      
40
Eng.Fouad

プライベート

  • メソッド、変数、コンストラクタ

プライベートと宣言されたメソッド、変数、およびコンストラクターは、宣言されたクラス内でのみアクセスできます。

  • クラスとインターフェース

プライベートアクセス修飾子は、最も制限の厳しいアクセスレベルです。クラスとインターフェースをプライベートにすることはできません。

privateとして宣言されている変数は、クラスにパブリックgetterメソッドが存在する場合、クラスの外部からアクセスできます。スーパークラスで保護されていると宣言されている変数、メソッド、およびコンストラクターには、他のパッケージのサブクラスまたは保護されたメンバーのクラスのパッケージ内の任意のクラスのみがアクセスできます。


保護された

  • クラスとインターフェース

保護されたアクセス修飾子は、クラスとインターフェイスに適用できません。

メソッド、フィールドは保護されていると宣言できますが、インターフェイス内のメソッドとフィールドは保護されていると宣言できません。

保護されたアクセスは、サブクラスにヘルパーメソッドまたは変数を使用する機会を与えますが、関係のないクラスがそれを使用しようとするのを防ぎます。


パブリック

publicと宣言されたクラス、メソッド、コンストラクター、インターフェイスなどは、他のクラスからアクセスできます。

したがって、パブリッククラス内で宣言されたフィールド、メソッド、ブロックには、Javaユニバースに属する任意のクラスからアクセスできます。

  • 異なるパッケージ

ただし、アクセスしようとしているパブリッククラスが別のパッケージにある場合は、パブリッククラスをインポートする必要があります。

クラスの継承のため、クラスのすべてのパブリックメソッドと変数はサブクラスに継承されます。


デフォルト-キーワードなし:

デフォルトのアクセス修飾子は、クラス、フィールド、メソッドなどのアクセス修飾子を明示的に宣言しないことを意味します

  • 同じパッケージ内

アクセス制御修飾子なしで宣言された変数またはメソッドは、同じパッケージ内の他のクラスで使用できます。インターフェイスのフィールドは暗黙的にpublic static finalであり、インターフェイスのメソッドはデフォルトでpublicです。

静的フィールドをオーバーライドすることはできません。オーバーライドしようとしてもエラーは表示されませんが、それ以外は機能しません。

関連する回答

参照リンク

http://docs.Oracle.com/javase/tutorial/Java/javaOO/accesscontrol.htmlhttp://www.tutorialspoint.com/Java/java_access_modifiers.htm

27
Nambi

Private :クラスへのアクセス制限

デフォルト(修飾子なし) :クラスとパッケージへの制限付きアクセス

保護された :クラス、パッケージおよびサブクラスへの制限付きアクセス(パッケージの内側と外側の両方)

Public :クラス、パッケージ(all)、およびサブクラスにアクセスできます。

18
samkit shah

違いは既に提供されているリンクで見つけることができますが、どちらを使用するかは通常「最小知識の原則」に帰着します。必要最小限の可視性のみを許可してください。

16
Joe Phillips

Javaの修飾子にアクセスします。

Javaアクセス修飾子は、Javaでアクセス制御を提供するために使用されます。

1.デフォルト:

同じパッケージ内のクラスにのみアクセス可能です。

例えば、

// Saved in file A.Java
package pack;

class A{
  void msg(){System.out.println("Hello");}
}

// Saved in file B.Java
package mypack;
import pack.*;

class B{
  public static void main(String args[]){
   A obj = new A(); // Compile Time Error
   obj.msg(); // Compile Time Error
  }
}

このアクセスは、パブリックおよび保護より制限されていますが、プライベートより制限されていません。

2.一般公開

どこからでもアクセスできます。 (グローバルアクセス)

例えば、

// Saved in file A.Java

package pack;
public class A{
  public void msg(){System.out.println("Hello");}
}

// Saved in file B.Java

package mypack;
import pack.*;

class B{
  public static void main(String args[]){
    A obj = new A();
    obj.msg();
  }
}

出力:こんにちは

3.プライベート

同じクラス内でのみアクセス可能.

あるクラスのプライベートメンバに別のクラスのプライベートメンバにアクセスしようとすると、コンパイルエラーが発生します。例えば、

class A{
  private int data = 40;
  private void msg(){System.out.println("Hello Java");}
}

public class Simple{
  public static void main(String args[]){
    A obj = new A();
    System.out.println(obj.data); // Compile Time Error
    obj.msg(); // Compile Time Error
  }
}

4.保護された

同じパッケージ内のクラスとサブクラスにのみアクセス可能

例えば、

// Saved in file A.Java
package pack;
public class A{
  protected void msg(){System.out.println("Hello");}
}

// Saved in file B.Java
package mypack;
import pack.*;

class B extends A{
  public static void main(String args[]){
    B obj = new B();
    obj.msg();
  }
}

出力:こんにちは

Enter image description here

14
Virtual

アクセス修飾子は、いくつかのレベルでアクセスを制限するためにあります。

Public: 同じパッケージ内にあるかどうかにかかわらず、基本的にどのクラスからでもアクセスできるのと同じくらい簡単です。

同じパッケージ内にいる場合にアクセスするには直接アクセスできますが、別のパッケージ内にいる場合はそのクラスのオブジェクトを作成できます。

デフォルト: どのクラスのパッケージからも同じパッケージ内でアクセス可能です。

アクセスするには、そのクラスのオブジェクトを作成します。しかし、あなたはパッケージの外でこの変数にアクセスすることはできません。

保護: あなたは他のパッケージのサブクラスと同じパッケージの変数にアクセスすることができます。だから基本的には デフォルト+継承 振る舞いです。

基本クラスで定義された保護フィールドにアクセスするには、子クラスのオブジェクトを作成します。

非公開: 同じクラスでアクセスできます。

非静的メソッドでは this referenceのおかげで直接アクセスできますが(コンストラクタ内でも)、静的メソッドでアクセスするにはクラスのオブジェクトを作成する必要があります。

14
Prashant

パッケージに表示されます。デフォルト。修飾子は必要ありません。

クラスにのみ表示されます( private )。

世界に見える( public )。

パッケージとすべてのサブクラスに表示されます( protected )。

変数とメソッドは、呼び出される修飾子なしで宣言できます。デフォルトの例

String name = "john";

public int age(){
    return age;
}

プライベートアクセス修飾子 - プライベート:

Privateと宣言されているメソッド、変数、およびコンストラクタは、宣言されているクラス自体の中でのみアクセスできます。プライベートアクセス修飾子は最も制限的なアクセスレベルです。クラスとインタフェースはプライベートにはできません。

プライベートと宣言された変数は、パブリックのgetterメソッドがクラス内に存在すれば、クラスの外からアクセスできます。

プライベート修飾子を使用することは、オブジェクトがそれ自体をカプセル化し、データを外部から隠すための主な方法です。

例:

Public class Details{

    private String name;

    public void setName(String n){
        this.name = n;
    }

    public String getName(){
        return this.name;
    }
}

公開アクセス修飾子 - 公開:

Publicとして宣言されたクラス、メソッド、コンストラクタ、インタフェースなどは、他のどのクラスからもアクセスできます。したがって、パブリッククラス内で宣言されたフィールド、メソッド、ブロックは、Javaユニバースに属する任意のクラスからアクセスできます。

ただし、アクセスしようとしているパブリッククラスが別のパッケージに含まれている場合は、そのパブリッククラスをインポートする必要があります。

クラス継承のため、クラスのすべてのパブリックメソッドと変数はそのサブクラスによって継承されます。

例:

public void cal(){

}

保護されたアクセス修飾子 - 保護された:

スーパークラスで保護されていると宣言された変数、メソッド、およびコンストラクタは、別のパッケージのサブクラス、または保護されているメンバーのクラスのパッケージ内の任意のクラスによってのみアクセスできます。

保護されたアクセス修飾子はクラスとインタフェースには適用できません。メソッド、フィールドは保護されていると宣言できますが、インターフェイス内のメソッドとフィールドは保護されていると宣言することはできません。

保護されたアクセスはサブクラスにヘルパーメソッドまたは変数を使用する機会を与えますが、無関係のクラスがそれを使用しようとするのを防ぎます。

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}
12
amila isura

このページのほとんどの回答を含め、非常に一般的に間違っている詳細について説明します。 "デフォルト"アクセス(アクセス修飾子が存在しない場合)は、必ずしもpackage-privateと同じではありません 。それは物事によって異なります。

  • 非メンバ型(つまり、他の型の内側で宣言されていないクラス、列挙型、インタフェース、および注釈型)は、デフォルトではパッケージプライベートです。 ( JLS§6.6.1

  • クラスメンバとコンストラクタはデフォルトでパッケージプライベートです。 ( JLS§6.6.1

  • 列挙型コンストラクタは デフォルトではprivate です。 (確かに、enumコンストラクタmustは非公開であり、それらを公開または保護しようとするとエラーになります)。列挙型定数はパブリックであり、アクセス指定子を許可しません。 enumの他のメンバーはデフォルトでパッケージプライベートです。 ( JLS§8.9

  • インターフェースおよび注釈型のすべてのメンバーは デフォルトではパブリック です。 (確かに、インタフェースのメンバーや注釈型mustはpublicになり、それらを非公開または保護にしようとするとエラーになります。)( JLS 9.3から9.5

12
Boann
  • public - アプリケーション内のどこからでもアクセス可能。

  • デフォルト - パッケージからアクセス可能。

  • protected - パッケージおよび他のパッケージのサブクラスからアクセス可能。同様に

  • private - そのクラスからのみアクセス可能。

12

このページは保護されたデフォルトのアクセス修飾子についてよく書いています

....保護された:保護されたアクセス修飾子は少しトリッキーであり、あなたは言うことができるデフォルトのアクセス修飾子のスーパーセットです。保護されたメンバーは、同じパッケージ内のアクセスに関する限り、デフォルトのメンバーと同じです。違いは、保護されたメンバーは、親クラスが存在するパッケージの外側にあるメンバーが宣言されているクラスのサブクラスにもアクセスできるということです。

しかし、これらの保護されたメンバーは「継承を通じてのみパッケージの外部からアクセス可能です」つまり、他のパッケージに含まれるサブクラス内のクラスの保護されたメンバーに、そのメンバーがサブクラス自体に存在するかのように直接アクセスできます。ただし、その保護されたメンバーは、親クラスの参照を使用してパッケージの外側のサブクラスからアクセスすることはできません。 …….

10
dameng

Davidの答えは、各アクセス修飾子の意味を示しています。それぞれを使用する場合については、外部使用を目的としたすべてのクラスと各クラスのメソッド(そのAPI)を公開し、それ以外はすべて非公開にすることをお勧めします。

時間が経てば、一部のクラスをパッケージ非公開にするタイミング、およびサブクラスで使用するために保護されている特定のメソッドを宣言するタイミングについて理解を深めることができます。

8
Dov Wasserman

注:これは、受け入れられた回答の 補足 です。

これはJava Access Modifiers に関連しています。

From Javaアクセス修飾子

Javaアクセス修飾子は、特定のクラスとそのフィールド、コンストラクタ、およびメソッドにアクセスできるクラスを指定します。アクセス修飾子は、クラス、そのコンストラクタ、フィールド、およびメソッドに対して別々に指定できます。 Javaアクセス修飾子は、日常会話ではJavaアクセス指定子とも呼ばれますが、正しい名前はJavaアクセス修飾子です。クラス、フィールド、コンストラクタ、およびメソッドは、4つの異なるJavaアクセス修飾子のうちの1つを持つことができます。

  • リスト項目
  • 非公開
  • デフォルト(パッケージ)
  • 保護された
  • パブリック

From クラスのメンバーへのアクセス制御 tutorials:

アクセスレベル修飾子は、他のクラスが特定のフィールドを使用できるか、特定のメソッドを呼び出すことができるかを決定します。アクセス制御には2つのレベルがあります。

  • 最上位レベルでは、public、またはpackage-private(明示的な修飾子なし)。
  • メンバーレベルでは、public、private、protected、またはpackage-private(明示的な修飾子なし)。

クラスは修飾子publicを使って宣言することができ、その場合そのクラスはあらゆる場所のすべてのクラスから見えるようになります。クラスが修飾子を持たない場合(デフォルト、package-privateとも呼ばれます)、それはそれ自身のパッケージ内でのみ可視です

次の表は、各修飾子によって許可されているメンバーへのアクセスを示しています。

╔═════════════╦═══════╦═════════╦══════════╦═══════╗
║ 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     ║
╚═════════════╩═══════╩═════════╩══════════╩═══════╝

最初のデータ列は、クラス自体がアクセスレベルで定義されたメンバにアクセスできるかどうかを示します。ご覧のとおり、クラスは常に自分のメンバーにアクセスできます。 2番目の列は、クラスと同じパッケージ内のクラスが(その親子関係に関係なく)メンバーにアクセスできるかどうかを示します。 3番目の列は、このパッケージの外部で宣言されたクラスのサブクラスがそのメンバにアクセスできるかどうかを示します。 4列目は、すべてのクラスがそのメンバーにアクセスできるかどうかを示します。

アクセスレベルは2つの方法であなたに影響を与えます。まず、Javaプラットフォームのクラスなど、他のソースからのクラスを使用する場合、アクセスレベルによって、自分のクラスで使用できるクラスのメンバが決まります。第二に、クラスを書くとき、あなたはあなたのクラスのすべてのメンバ変数とすべてのメソッドが持つべきアクセスレベルを決定する必要があります。

Public Protected Defaultとprivateはアクセス修飾子です。

それらはカプセル化、またはクラスの内容を隠して表示するためのものです。

  1. クラスはパブリックまたはデフォルトにすることができます
  2. クラスメンバーは、パブリック、保護、デフォルト、またはプライベートにすることができます。

Privateはクラス外からはアクセスできないdefaultはパッケージ内でのみアクセス可能です。それを拡張するすべてのクラスと同様に、パッケージ内で保護されています。公衆はすべての人に開かれています。

通常、メンバ変数はプライベートとして定義されていますが、メンバメソッドはパブリックです。

5
richa_v

多くの場合、私は現実の世界の類推を作成することによって、あらゆる言語の基本概念を覚えることが可能になることに気づいた。これがJavaのアクセス修飾子を理解するための私のアナロジーです:

あなたはあなたが大学の学生であり、あなたには週末にあなたを訪ねてくる友人がいるとしましょう。キャンパスの真ん中に大学の創設者の大きな像があるとします。

  • あなたが彼をキャンパスに連れて行くとき、あなたとあなたの友人が最初に見るのはこの像です。これは、キャンパス内を歩く人なら誰でも大学の許可なしに像を見ることができることを意味します。これは _ public _ として像を作ります。

  • 次に、あなたはあなたの友達をあなたの寮に連れて行きたいのですが、そのためにあなたは彼を訪問者として登録する必要があります。これは、彼がキャンパス内のさまざまな建物に入るためのアクセスパス(これはあなたのものと同じです)を取得することを意味します。これは彼のアクセスカードを _ protected _ にするでしょう。

  • あなたの友人はキャンパスのWiFiにログインしたいのですが、ログインするための資格情報がありません。彼がオンラインになることができる唯一の方法はあなたが彼とあなたのログインを共有する場合です。 (覚えておいて、大学に行くすべての学生はまたこれらのログイン資格情報を持っています)。これにより、ログイン認証情報が NO MODIFIER になります。

  • 最後に、あなたの友人は、ウェブサイトに掲載されている学期の進捗報告を読みたいと思っています。ただし、すべての学生は、キャンパスWebサイトのこのセクションにアクセスするための独自の個人ログインを持っています。これにより、これらの認証情報は _ private _ になります。

お役に立てれば!

5
Greedy Coder

あなたがアクセス修飾子を考えているとき、ちょうどそのように考えてください( 変数 methods の両方に当てはまります):

public - >どこからでもアクセス可能
private - >宣言されているのと同じクラス内でのみアクセス可能

defaultprotectedに関しては混乱が生じる

default - >アクセス修飾キーワードが存在しません。これはクラスのパッケージ内でのみ利用可能であることを意味します。 どこにも そのパッケージの外側ではアクセスできます。

protected - > defaultよりも少し厳密ではなく、同じパッケージクラスとは別に、 package 以外のサブクラスからアクセスすることができます。

4
Pritam Banerjee

それはすべてカプセル化(またはジョー・フィリップスが述べたように、最低限の知識)です。

最も限定的な(プライベート)から始めて、後でより制限の少ない修飾子が必要かどうかを確認します。

私たちは皆、private、publicなどのメソッド修飾子とメンバー修飾子を使用していますが、開発者が行うことの少ないことの1つは、パッケージを使用してorganize論理的にコーディングすることです。

例:機密性の高いセキュリティメソッドを「セキュリティ」パッケージに入れることができます。次に、このパッケージのセキュリティ関連コードの一部にアクセスするパブリッククラスを配置しますが、他のセキュリティクラスは保持しますpackage private。したがって、他の開発者は、このパッケージの外部から公開されているクラスのみを使用できます(修飾子を変更しない限り)。これはセキュリティ機能ではありませんが、ガイド使用法です。

Outside world -> Package (SecurityEntryClass ---> Package private classes)

別のことは、互いに多くの依存関係にあるクラスが同じパッケージになり、依存関係が強すぎる場合に最終的にリファクタリングまたはマージされる可能性があることです。

逆に、すべてをpublicに設定すると、何にアクセスすべきか、またはアクセスすべきでないかが明確にならないため、多くのjavadoc(コンパイラを介して何も強制されない... )。

2

アクセス修飾子

enter image description here

イェンコフの記事

次の表に、各Javaアクセス修飾子を適用できるJava構成要素の概要を示します。 enter image description here

プライベート

メソッドまたは変数がプライベートとしてマークされている(プライベートアクセス修飾子が割り当てられている)場合、同じクラス内のコードのみが変数にアクセスするか、メソッドを呼び出すことができます。サブクラス内のコードは変数またはメソッドにアクセスできず、外部クラスのコードも使用できません。

クラスにプライベートアクセス修飾子を付けることはできません。プライベートアクセス修飾子でクラスをマークすると、他のクラスがそのクラスにアクセスできなくなります。つまり、クラスを実際に使用することはできません。したがって、プライベートアクセス修飾子はクラスに対して許可されていません。

default

デフォルトのJavaアクセス修飾子は、アクセス修飾子をまったく記述しないことによって宣言されます。デフォルトのアクセス修飾子とは、クラス自体内のコードとこのクラスと同じパッケージ内のクラス内のコードが、デフォルトのアクセス修飾子が割り当てられているクラス、フィールド、コンストラクター、またはメソッドにアクセスできることを意味します。したがって、デフォルトのアクセス修飾子は、パッケージアクセス修飾子とも呼ばれます。

保護された

保護されたアクセス修飾子は、デフォルトのアクセス修飾子と同じアクセスを提供しますが、サブクラスがスーパークラスの保護されたメソッドとメンバー変数(フィールド)にアクセスできることも追加されます。これは、サブクラスがスーパークラスと同じパッケージにない場合でも同様です。

パブリック

Javaアクセス修飾子publicは、アクセスするコードの場所に関係なく、すべてのコードがクラス、フィールド、コンストラクター、またはメソッドにアクセスできることを意味します。アクセスするコードは、異なるクラスおよび異なるパッケージに存在できます。

2
yoAlex5