一部のドキュメントで使用されている「パッケージ プライベート」という用語と、「デフォルト アクセス」の使用法について、私は少し混乱しています。package-private と default アクセスはどちらも protected と同義ではありませんか?
7 に答える
はい、ほとんど同じです。protected 修飾子は、メンバーが (package-private と同様に) 独自のパッケージ内でのみアクセスできることを指定し、さらに、別のパッケージ内のそのクラスのサブクラスによってアクセスできることを指定します。
「デフォルト」アクセス修飾子 (いずれも明示的に指定されていないもの) は「package-private」です。これは、同じパッケージ内のものだけがそれらにアクセスできることを意味します。ただし、同じパッケージに含まれているということは、クラス間の継承関係については何も意味しません。これは純粋に命名規則です。
「保護」とは、同じパッケージ内のクラスだけでなく、サブクラスも (サブクラスがどのパッケージに含まれているかに関係なく) アクセスできることを意味します。
クラスのデフォルトアクセスはpackage-privateですが、インターフェイスメンバーのデフォルトアクセスはpublicです。
例えば
public interface I {
int A = 1;
// same as
public static final int A = 1;
void method();
// same as
public abstract void method();
class C { }
// same as
public static class C { }
}
インターフェイスのデフォルトのアクセスルールは、クラスの場合と同じではありません。
パッケージ プライベート アクセスとデフォルト アクセスは同義語です。オブジェクトは、クラスが同じパッケージ内にあるオブジェクトの保護されたメンバーにもアクセスできます。オブジェクトは、パッケージに関する条件なしで、そのスーパークラスの保護されたメンバーにアクセスすることもできます。具体例として:
package ab;
class A {
protected void foo() {}
void dd(){}
}
class C {
void aa(){
A a = new A();
a.foo(); //legal
a.dd(); //legal
}
}
package sub;
class D extends A{
void ac(){
foo(); //legal ..
dd(); //illegal.. because dd has default access..
}
class E {
void ee(){
A a = new A();
a.foo(); //illegal
a.dd(); //illegal
}
「パッケージ プライベート」とデフォルト アクセスは同じです。1.1.2/3 前後のコンパイラの初期リリースでは、'package' は許可された修飾子でしたが、無視されました。つまり、修飾子がないこと、つまり 'package private' と同じ意味でした。/*package*/
その後まもなく、そのような状況で (コメントとして)置くための短命の流行がありました。同様に、同期クラスなどを宣言することもできましたが、実際のセマンティック効果はありませんでした。
どちらも、他のパッケージの派生クラスに拡張される「保護」と同じではありません。
Java言語仕様から
- 6.6.5 例: デフォルト アクセス フィールド、メソッド、およびコンストラクタアクセス修飾子 public、protected、または private のいずれも指定されていない場合、クラス メンバまたはコンストラクタは、クラスが含まれるクラスの宣言を含むパッケージ全体でアクセス可能です。 member が宣言されていますが、クラス メンバーまたはコンストラクターは他のパッケージではアクセスできません。
パブリック クラスにデフォルト アクセスのメソッドまたはコンストラクタがある場合、このメソッドまたはコンストラクタは、このパッケージの外部で宣言されたサブクラスにアクセスできないか、継承されません。
defaultとpackage-privateはどちらも同じです。つまり、どちらも同じパッケージに含まれるまで、どのクラスでも使用できます。
パッケージ プライベートという用語は、実際にはプライベート修飾子の意味で呼ばれます。プライベートとは、同じクラスでのみ使用でき、他のクラスやサブクラスが同じパッケージ内またはパッケージ外にアクセスできないことを意味します。
したがって、package-privateはdefaultと同じことを意味します。