Javaでのpublic、protected、package-private、およびprivateの違いは何ですか?
-
03-07-2019 - |
質問
Javaで、各アクセス修飾子、つまりデフォルト(プライベート)、 public
、 protected
および private
、 class
および interface
を作成し、継承を処理しますか?
解決
公式チュートリアルは役に立つかもしれません。
│ Class │ Package │ Subclass │ Subclass │ World │ │ │(same pkg)│(diff pkg)│ ────────────┼───────┼─────────┼──────────┼──────────┼──────── public │ + │ + │ + │ + │ + ────────────┼───────┼─────────┼──────────┼──────────┼──────── protected │ + │ + │ + │ + │ ────────────┼───────┼─────────┼──────────┼──────────┼──────── no modifier │ + │ + │ + │ │ ────────────┼───────┼─────────┼──────────┼──────────┼──────── private │ + │ │ │ │ + : accessible blank : not accessible
他のヒント
(注意:私はJavaプログラマーではありません。Perlプログラマーです。Perlには正式な保護がありません。おそらくこの問題をよく理解している理由でしょう:))
プライベート
あなたが思うように、それが宣言されているクラスのみがそれを見ることができます。
パッケージプライベート
宣言されたパッケージでのみ表示および使用できます。これはJavaのデフォルトです(一部の人は間違いと見なします)。
保護
パッケージプライベート+は、サブクラスまたはパッケージメンバーが見ることができます。
公開
誰でも見ることができます。
公開済み
私が制御するコードの外側に表示されます。 (Java構文ではありませんが、この議論にとって重要です。)
C ++は、" friend"という追加のレベルを定義します。そして、あなたがそれについて知っていることが少ないほど良い。
いつ何を使用すべきですか?全体の考え方は、情報を隠すためのカプセル化です。可能な限り、ユーザーに対して何かがどのように行われるかの詳細を非表示にする必要があります。どうして?そのため、後で変更することができ、誰かのコードを壊すことはありません。これにより、オーバーホールしたコードを誰かが使用していることを心配することなく、バグを最適化、リファクタリング、再設計、修正できます。
そのため、経験則では、必要なだけ見えるようにします。プライベートから始めて、必要に応じて可視性を追加します。ユーザーが知るために絶対に必要なことだけを公開します。公開するすべての詳細は、システムを再設計する能力を低下させます。
ユーザーが内部を公開してオーバーライドできるようにするのではなく、動作をカスタマイズできるようにしたい場合は、多くの場合、それらの勇気をオブジェクトに押し込み、そのインターフェースを公開することをお勧めします。そうすれば、新しいオブジェクトを簡単にプラグインできます。たとえば、CDプレーヤーを作成していて、「このCDについての情報を検索する」を希望する場合は、それらのメソッドを公開するのではなく、ビットのカスタマイズが可能です。すべての機能を独自のオブジェクトに入れ、オブジェクトのゲッター/セッターのみを公開します。このように、あなたの内臓を露出することについてケチなことは、良い構図と懸念の分離を促進します
個人的には、「プライベート」だけを使います。および「パブリック」。多くのオブジェクト指向言語にはそれがあります。 "保護されています"便利かもしれませんが、それは本当にチートです。インターフェースがプライベート以上のものになると、それはあなたのコントロールの外にあり、他の人のコードを調べて用途を見つける必要があります。
ここで、「公開」というアイデアがあります。インターフェースを変更する(リファクタリングする)には、それを使用しているすべてのコードを見つけて変更する必要があります。インターフェイスがプライベートである場合、問題はありません。保護されている場合は、すべてのサブクラスを検索する必要があります。公開されている場合は、コードを使用するすべてのコードを見つけてください。たとえば、内部使用専用の企業コードで作業している場合、インターフェイスがパブリックであるかどうかは関係ありません。企業リポジトリからすべてのコードを取得できます。しかし、インターフェースが「公開」されている場合、コントロール外でそれを使用するコードがある場合、あなたはうんざりしています。そのインターフェイスをサポートするか、コードを壊す危険があります。保護されたインターフェイスでさえ、公開されていると見なすことができます(そのため、保護されたインターフェイスを気にしないのです)。
多くの言語は、public / protected / privateの階層的な性質があまりにも制限的であり、現実と一致していないと感じています。そのために、特性クラスの概念がありますが、それは別のショーです。
これは、テーブルのより良いバージョンです。 (モジュール用の列を備えた将来の証拠。)
説明
-
private メンバー(
i
)は、宣言された同じクラス内でのみのみアクセスできます。 -
アクセス修飾子なし(
j
)を持つメンバーは、同じパッケージ内のクラス内でのみアクセス可能です。 -
保護されたメンバー(
k
)は、同じパッケージのすべてのクラス内および他のパッケージのサブクラス内でアクセスできます。< -
public メンバー(
l
)は、すべてのクラスからアクセスできます(宣言されているパッケージをエクスポートしないモジュール。
選択する修飾子はどれですか
アクセス修飾子は、カプセル化(*)を誤って壊さないようにするツールです。メンバーがクラス、パッケージ、クラス階層の内部にいるのか、まったく内部にいないのかを自問し、それに応じてアクセスレベルを選択します。
例:
- フィールド
long internalCounter
は、可変で実装の詳細であるため、おそらくプライベートにする必要があります。 - (同じパッケージ内の)ファクトリクラスでのみインスタンス化する必要があるクラスには、パッケージの外部から直接呼び出すことはできないため、パッケージ制限コンストラクターが必要です。
- 内部の
void beforeRender()
メソッドは、レンダリングの直前に呼び出され、サブクラスでフックとして使用されます。 - GUIコードから呼び出される
void saveGame(File dst)
メソッドはpublicである必要があります。
(*)正確なカプセル化とは
| 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 | ✔ | ✘ | ✘ | ✘
簡単なルール。すべてをプライベートとして宣言することから始めます。そして、ニーズが生じ、デザインがそれを保証するとき、一般の方に向かって進歩します。
メンバーを公開するとき、表現の選択肢または抽象化の選択肢を公開するかどうかを自問します。 1つ目は、観察可能な動作ではなく、実際の表現に多くの依存関係を導入するため、避けたいものです。
一般的なルールとして、サブクラス化によるメソッド実装のオーバーライドを避けるようにしています。ロジックを台無しにするのは簡単すぎます。オーバーライドする場合は、抽象保護メソッドを宣言します。
また、リファクタリング時に問題が発生しないように、オーバーライド時に@Overrideアノテーションを使用します。
実際には、単純なグリッドが示すよりも少し複雑です。グリッドは、アクセスが許可されているかどうかを示しますが、アクセスを正確に構成するものは何ですか?また、アクセスレベルは、ネストされたクラスおよび継承と複雑な方法で対話します。
&quot;デフォルト&quot;アクセス(キーワードがないことで指定)は、 package-private 。例外:インターフェイスでは、修飾子はパブリックアクセスを意味しません。 public以外の修飾子は禁止されています。列挙定数は常にパブリックです。
概要
このアクセス指定子を持つメンバーへのアクセスは許可されていますか?
- メンバーは
private
:メンバーが呼び出しコードと同じクラス内で定義されている場合のみ。 - メンバーはパッケージプライベート:呼び出しコードがメンバーのすぐに含まれるパッケージ内にある場合のみ。
- メンバーは
protected
:同じパッケージ、または呼び出し元コードを含むクラスのスーパークラスでメンバーが定義されている場合。 - メンバーは
public
:はい。
アクセス指定子の適用対象
ローカル変数と仮パラメータは、アクセス指定子を取ることができません。スコーピングルールに従って、本質的に外部からアクセスできないため、事実上プライベートです。
最上位スコープのクラスでは、 public
およびpackage-privateのみが許可されます。この設計上の選択は、おそらく protected
および private
がパッケージレベルで冗長になるためです(パッケージの継承はありません)。
すべてのアクセス指定子は、クラスメンバー(コンストラクター、メソッド、静的メンバー関数、ネストされたクラス)で使用できます。
関連: Javaクラスのアクセシビリティ
注文
アクセス指定子は厳密に順序付けることができます
公開&gt;保護&gt;パッケージプライベート&gt;プライベート
は、 public
が最も多くのアクセスを提供し、 private
が最も少ないことを意味します。プライベートメンバーで可能な参照は、パッケージプライベートメンバーでも有効です。パッケージプライベートメンバーへの参照は、保護されたメンバーなどで有効です。 (同じパッケージ内の他のクラスへの保護されたメンバーへのアクセス権を与えることは間違いと見なされました。)
注意事項
- クラスのメソッドは、他のオブジェクトのプライベートメンバーへのアクセスを許可されています 同じクラス。より正確には、クラスCのメソッドは、Cのサブクラスのオブジェクト上のCのプライベートメンバーにアクセスできます。Javaは、クラスのみによるインスタンスごとのアクセス制限をサポートしていません。 (
private [this]
を使用してサポートしているScalaと比較してください。) - オブジェクトを構築するには、コンストラクターにアクセスする必要があります。したがって、すべてのコンストラクタがプライベートである場合、クラスはクラス内にあるコード(通常は静的ファクトリメソッドまたは静的変数初期化子)によってのみ構築できます。同様に、パッケージプライベートコンストラクタまたは保護されたコンストラクタの場合。
- プライベートコンストラクターのみを持つことは、Javaがサブクラスのコンストラクターを暗黙的または明示的にスーパークラスコンストラクターを呼び出す必要があるため、クラスを外部でサブクラス化できないことも意味します。 (ただし、サブクラス化するネストされたクラスを含めることができます。)
内部クラス
また、内部クラスなど、ネストされたスコープを考慮する必要があります。複雑さの例としては、内部クラスにメンバーがあり、それ自体がアクセス修飾子を取ることができます。したがって、パブリックメンバーを持つプライベートな内部クラスを持つことができます。メンバーにアクセスできますか? (以下を参照。)一般的なルールは、スコープを見て再帰的に考え、各レベルにアクセスできるかどうかを確認することです。
ただし、これは非常に複雑で、
経験則:
-
private
:クラススコープ。 -
default
(またはpackage-private
):パッケージスコープ。 -
protected
:package scope + child
(packageと同様ですが、異なるパッケージからサブクラス化できます)。 protected修飾子は、常に「親子」を保持します;関係。 -
public
:どこでも。
その結果、アクセス権を3つの権利に分割した場合:
- (D)irect (同じクラス内のメソッドから、または&quot; this&quot;構文を使用して呼び出します。)
- (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 |
+—————————————————+————————————+———————————+
非常に短い
-
public
:どこからでもアクセスできます。 -
protected
:同じパッケージのクラスおよび任意のパッケージにあるサブクラスからアクセス可能。 - デフォルト(修飾子を指定しない):同じパッケージのクラスからアクセス可能。
-
private
:同じクラス内でのみアクセス可能。
Javaで最も誤解されているアクセス修飾子は、 protected
です。サブクラスがそれを見ることができるという例外を除いて、デフォルト修飾子に似ていることを知っています。しかし、どのように?以下に、混乱を明確にした例を示します。
-
2つのクラスがあると仮定します。
Father
およびSon
、それぞれ独自のパッケージ:package fatherpackage; public class Father { } ------------------------------------------- package sonpackage; public class Son extends Father { }
-
保護されたメソッド
foo()
をFather
に追加しましょう。package fatherpackage; public class Father { protected void foo(){} }
-
4つのコンテキストでメソッド
foo()
を呼び出すことができます:-
foo()
が定義されている同じパッケージ(fatherpackage
)にあるクラス内:package fatherpackage; public class SomeClass { public void someMethod(Father f, Son s) { f.foo(); s.foo(); } }
-
サブクラス内で、現在のインスタンスで
this
またはsuper
を使用:package sonpackage; public class Son extends Father { public void sonMethod() { this.foo(); super.foo(); } }
-
同じクラスの型の参照:
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(); } }
-
タイプが親クラスであり、
foo()
が定義されているパッケージ(fatherpackage
)[これはコンテキスト番号内に含めることができます。 1]:package fatherpackage; public class Son extends Father { public void sonMethod(Father f) { f.foo(); } }
-
-
次の状況は無効です。
-
タイプが親クラスであり、
foo()
が定義されているパッケージ(fatherpackage
):package sonpackage; public class Son extends Father { public void sonMethod(Father f) { f.foo(); // compilation error } }
-
サブクラスのパッケージ内の非サブクラス(サブクラスは親から保護されたメンバーを継承し、非サブクラスに対してプライベートにします):
package sonpackage; public class SomeClass { public void someMethod(Son s) throws Exception { s.foo(); // compilation error } }
-
プライベート
- メソッド、変数、コンストラクタ
プライベートとして宣言されているメソッド、変数、コンストラクターには、宣言されたクラス自体内でのみアクセスできます。
- クラスとインターフェース
プライベートアクセス修飾子は、最も制限の厳しいアクセスレベルです。クラスとインターフェースをプライベートにすることはできません。
注
プライベートに宣言されている変数は、クラスにパブリックgetterメソッドが存在する場合、クラスの外部からアクセスできます。 スーパークラスで保護されていると宣言されている変数、メソッド、およびコンストラクターには、他のパッケージのサブクラスまたは保護されたメンバーのクラスのパッケージ内のクラスのみがアクセスできます。
保護
- クラスとインターフェース
保護されたアクセス修飾子は、クラスとインターフェイスに適用できません。
メソッド、フィールドは保護されていると宣言できますが、インターフェイス内のメソッドとフィールドは保護されていると宣言できません。
注
保護されたアクセスは、サブクラスにヘルパーメソッドまたは変数を使用する機会を与えますが、関係のないクラスはそれを使用しようとしません。
publicと宣言されたクラス、メソッド、コンストラクター、インターフェースなどは、他のクラスからアクセスできます。 したがって、パブリッククラス内で宣言されたフィールド、メソッド、ブロックには、Javaユニバースに属する任意のクラスからアクセスできます。 ただし、アクセスしようとしているパブリッククラスが別のパッケージにある場合は、パブリッククラスをインポートする必要があります。 クラスの継承のため、クラスのすべてのパブリックメソッドと変数はサブクラスに継承されます。 デフォルトのアクセス修飾子は、クラス、フィールド、メソッドなどのアクセス修飾子を明示的に宣言しないことを意味します。 アクセス制御修飾子なしで宣言された変数またはメソッドは、同じパッケージ内の他のクラスで使用できます。インターフェイスのフィールドは暗黙的にpublic static finalであり、インターフェイスのメソッドはデフォルトでpublicです。 注 静的フィールドはオーバーライドできません。オーバーライドしようとしてもエラーは表示されません。
しかし、それ以外の場合は機能しません。 http://docs.oracle.com/javase/tutorial/ java / javaOO / accesscontrol.html
http://www.tutorialspoint.com/java/java_access_modifiers.htm
公開
デフォルト-キーワードなし:
関連する回答
参照リンク
プライベート:クラスのみへのアクセス制限
デフォルト(修飾子なし):クラスおよびパッケージへの制限付きアクセス
保護:クラス、パッケージ、およびサブクラス(パッケージの内部と外部の両方)への制限付きアクセス
パブリック:クラス、パッケージ(すべて)、およびサブクラスにアクセス可能...要するに、どこでも。
違いは、すでに提供されているリンクで見つけることができますが、通常、どちらを使用するかは「最小知識の原則」に帰着します。必要な最小限の可視性のみを許可します。
アクセス修飾子は、いくつかのレベルでアクセスを制限するためにあります。
公開:基本的には、同じパッケージ内にあるかどうかにかかわらず、どのクラスからでもアクセスできるほど簡単です。
同じパッケージにいる場合にアクセスするには直接アクセスできますが、別のパッケージにいる場合はクラスのオブジェクトを作成できます。
デフォルト:同じパッケージ内のどのクラスのパッケージからでもアクセスできます。
アクセスするには、クラスのオブジェクトを作成できます。ただし、パッケージ外ではこの変数にアクセスできません。
保護されている:同じパッケージ内の変数と他のパッケージ内のサブクラスにアクセスできます。 基本的にデフォルト+継承の動作です。
基本クラスで定義された保護フィールドにアクセスするには、子クラスのオブジェクトを作成できます。
プライベート:同じクラスでアクセスできます。
非静的メソッドでは、 this 参照(コンストラクターでも)のために直接アクセスできますが、静的メソッドでアクセスするには、クラスのオブジェクトを作成する必要があります。
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();
}
}
出力:こんにちは
このページのほとんどの回答を含め、非常に一般的に間違っている詳細に対処したいだけです。 &quot;デフォルト&quot;アクセス(アクセス修飾子が存在しない場合)は、常にpackage-privateと同じではありません。それは物によって異なります。
-
非メンバータイプ(つまり、クラス、列挙、インターフェイス、および別のタイプ内で宣言されていない注釈タイプ)は、デフォルトでパッケージプライベートです。 ( JLS&#167; 6.6.1 )
-
クラスのメンバーとコンストラクターは、デフォルトではパッケージプライベートです。 ( JLS&#167; 6.6.1 )
-
Enumコンストラクタは、デフォルトではプライベートです。 (実際、列挙型コンストラクターはプライベートである必要があります 必要があり、パブリックまたは保護しようとするとエラーになります)。列挙定数はパブリックであり、アクセス指定子を許可しません。列挙型の他のメンバーは、デフォルトでパッケージプライベートです。 ( JLS&#167; 8.9 )
-
インターフェースおよび注釈タイプのすべてのメンバーは、デフォルトで公開です。 (実際、インターフェースおよび注釈タイプのメンバーはパブリックである必要があり、それらをプライベートまたは保護しようとするとエラーになります。)(JLS&#167; 9.3から9.5 )
-
public -アプリケーションのどこからでもアクセス可能。
-
デフォルト-パッケージからアクセス可能。
-
protected -パッケージおよび他のパッケージのサブクラスからアクセス可能。
-
プライベート-クラスからのみアクセス可能。
パッケージに表示されます。デフォルト。修飾子は必要ありません。
クラスのみに表示されます(プライベート)。
世界に公開(公開)。
パッケージおよびすべてのサブクラスに表示されます(保護されている)。
変数とメソッドは、呼び出される修飾子なしで宣言できます。デフォルトの例:
String name = "john";
public int age(){
return age;
}
プライベートアクセス修飾子-private:
プライベートとして宣言されたメソッド、変数、およびコンストラクターは、宣言されたクラス自体内でのみアクセスできます。プライベートアクセス修飾子は、最も制限の厳しいアクセスレベルです。クラスとインターフェースをプライベートにすることはできません。
プライベートに宣言された変数は、クラスにパブリックgetterメソッドが存在する場合、クラスの外部からアクセスできます。
private修飾子の使用は、オブジェクトがそれ自体をカプセル化し、データを外部から隠す主な方法です。
例:
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(){
}
}
このページは、保護された&amp ;デフォルトのアクセス修飾子
.... 保護:保護されたアクセス修飾子は少し注意が必要であり、デフォルトのアクセス修飾子のスーパーセットであると言えます。保護されたメンバーは、同じパッケージ内のアクセスに関する限り、デフォルトのメンバーと同じです。違いは、保護されたメンバーは、親クラスが存在するパッケージの外部にある、メンバーが宣言されているクラスのサブクラスからもアクセスできることです。
ただし、これらの保護されたメンバーは、継承を介してのみパッケージ外でアクセスできます&#8220;。つまり、メンバーがサブクラス自体に存在するかのように、他のパッケージに存在するサブクラスにあるクラスの保護されたメンバーに直接アクセスできます。ただし、その保護されたメンバーは、親クラスの参照を使用してパッケージ外のサブクラスでアクセスすることはできません。 ....
Davidの答えは、各アクセス修飾子の意味を提供します。それぞれをいつ使用するかについては、すべてのクラスと、外部使用(API)を目的とする各クラスのメソッド、およびその他すべてをプライベートにすることをお勧めします。
時間の経過とともに、一部のクラスをパッケージプライベートにするとき、およびサブクラスで使用するために保護されている特定のメソッドを宣言するときの感覚を身に付けます。
注:これは、承認された回答の単なる補足です。
これは、Java アクセス修飾子に関連しています。
Javaアクセス修飾子は、特定のクラスにアクセスできるクラスを指定します クラスとそのフィールド、コンストラクター、メソッド。アクセス修飾子は クラス、そのコンストラクター、フィールド、および メソッド。 Javaアクセス修飾子は、毎日参照されることもあります Javaアクセス指定子としての音声、ただし正しい名前はJavaアクセス 修飾子。クラス、フィールド、コンストラクター、およびメソッドは、 4つの異なるJavaアクセス修飾子:
- リストアイテム
- プライベート
- default(パッケージ)
- 保護されている
- 公開
クラスのメンバーへのアクセスの制御チュートリアルから:
アクセスレベル修飾子は、他のクラスが 特定のフィールドまたは特定のメソッドを呼び出します。 2つのレベルがあります アクセス制御の:
- トップレベルで&#8212;パブリックまたはパッケージプライベート(明示的な修飾子なし)。
- メンバーレベルで、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はアクセス修飾子です。
これらは、カプセル化、またはクラスのコンテンツの非表示と表示を目的としています。
- クラスはパブリックまたはデフォルトにすることができます
- クラスメンバーは、public、protected、default、またはprivateです。
プライベートはクラス外ではアクセスできません デフォルトはパッケージ内でのみアクセス可能です。 パッケージおよびそれを拡張するクラスで保護されています。 誰でも利用できます。
通常、メンバー変数はプライベートに定義されていますが、メンバーメソッドはパブリックです。
多くの場合、実世界の類推を作成することで、あらゆる言語の基本概念を思い出すことができることに気付きました。 Javaのアクセス修飾子を理解するための私の例えは次のとおりです。
あなたが大学の学生で、週末にあなたを訪ねてくる友人がいると仮定しましょう。キャンパスの中央に大学の創設者の大きな像が存在するとします。
-
彼をキャンパスに連れて行くとき、あなたとあなたの友人が最初に目にするのはこの像です。つまり、キャンパス内を歩く人は誰でも大学の許可なしに像を見ることができます。これにより、像は PUBLIC になります。
-
次に、友人を寮に連れて行きたいのですが、そのためには訪問者として登録する必要があります。これは、キャンパス内のさまざまな建物に入るためのアクセスパス(あなたと同じ)を取得することを意味します。これにより、彼のアクセスカードは PROTECTED になります。
-
友達がキャンパスのWiFiにログインしようとしていますが、ログインするための資格情報がありません。彼がオンラインにできる唯一の方法は、あなたが彼とあなたのログインを共有することです。 (大学に行くすべての学生もこれらのログイン資格情報を所有していることを忘れないでください)。これにより、ログイン資格情報が変更なしになります。
-
最後に、あなたの友人は、ウェブサイトに投稿されている学期の進捗レポートを読みたいと思っています。ただし、すべての学生は、キャンパスWebサイトのこのセクションにアクセスするための独自の個人ログインを持っています。これにより、これらの資格情報は PRIVATE になります。
これがお役に立てば幸いです!
アクセス修飾子を考えているときは、このように考えるだけです(変数とメソッドの両方に適用されます):
public
-&gt;どこからでもアクセス可能
private
-&gt;宣言されている同じクラス内でのみアクセス可能
default
および protected
default
-&gt;アクセス修飾子キーワードはありません。これは、クラスのパッケージ内で厳密に使用できることを意味します。 どこにもアクセスできない
protected
-&gt; default
よりわずかに厳密ではなく、宣言されている package の外部のサブクラスからアクセスできる同じパッケージクラスは別です。
それはすべてカプセル化についてです(またはジョーフィリップスが述べたように、最低限の知識)。
最も制限の厳しい(プライベート)から始め、後で制限の緩い修飾子が必要かどうかを確認します。
私たちはすべて、private、publicなどのメソッドおよびメンバー修飾子を使用しますが、開発者が行うには少なすぎることの1つは、パッケージを使用してコードを論理的に整理することです
例: 機密性の高いセキュリティメソッドを「セキュリティ」パッケージに入れることができます。 次に、このパッケージにセキュリティ関連のコードの一部にアクセスするパブリッククラスを配置しますが、他のセキュリティクラスはパッケージプライベートのままにします。 したがって、他の開発者は、このパッケージの外部から公開されているクラスのみを使用できます(修飾子を変更しない限り)。 これはセキュリティ機能ではありませんが、使用方法をガイドします。
Outside world -> Package (SecurityEntryClass ---> Package private classes)
別のことは、互いに多くの依存関係にあるクラスが同じパッケージになり、依存関係が強すぎる場合に最終的にリファクタリングまたはマージされる可能性があることです。
反対にすべてを public に設定すると、何にアクセスすべきか、またはアクセスすべきでないかが明確にならないため、多くのjavadocが作成される可能性があります(コンパイラを介して何も強制されません) ...)。