Javaの「保護された」アクセス修飾子
1. 概要
Javaプログラミング言語では、フィールド、コンストラクター、メソッド、およびクラスをアクセス修飾子でマークできます。 このチュートリアルでは、保護されたアクセスについて説明します。
2. 保護されたキーワード
privateとして宣言された要素には、宣言されたクラスからのみアクセスできますが、 protected キーワードは、同じパッケージのサブクラスとメンバーからのアクセスを許可します。
protected キーワードを使用して、パッケージまたはクラス階層の内部と見なす必要があるメソッドとフィールド、および外部コードに公開するメソッドとフィールドを決定します。
3. 保護されたフィールド、メソッド、およびコンストラクターの宣言
まず、 protected フィールド、メソッド、およびコンストラクターを含むFirstClassという名前のクラスを作成しましょう。
public class FirstClass {
protected String name;
protected FirstClass(String name) {
this.name = name;
}
protected String getName() {
return name;
}
}
この例では、 protected キーワードを使用して、FirstClassと同じパッケージ内のクラスおよびFirstClassのサブクラスへのこれらのフィールドへのアクセスを許可しています。 ]。
4. 保護されたフィールド、メソッド、およびコンストラクターへのアクセス
4.1. 同じパッケージから
次に、FirstClassと同じパッケージで宣言された新しいGenericClassを作成して、protectedフィールドにアクセスする方法を見てみましょう。
public class GenericClass {
public static void main(String[] args) {
FirstClass first = new FirstClass("random name");
System.out.println("FirstClass name is " + first.getName());
first.name = "new name";
}
}
この呼び出しクラスはFirstClass、と同じパッケージに含まれているため、すべての保護されたフィールド、メソッド、およびコンストラクターを表示および操作できます。
4.2. 別のパッケージから
次に、FirstClassとは異なるパッケージで宣言されたクラスのこれらのフィールドを操作してみましょう。
public class SecondGenericClass {
public static void main(String[] args) {
FirstClass first = new FirstClass("random name");
System.out.println("FirstClass name is "+ first.getName());
first.name = "new name";
}
}
ご覧のとおり、コンパイルエラーが発生します:
The constructor FirstClass(String) is not visible
The method getName() from the type FirstClass is not visible
The field FirstClass.name is not visible
これは、protectedキーワードを使用して期待していたこととまったく同じです。 これは、SecondGenericClassがFirstClassと同じパッケージに含まれておらず、サブクラス化されていないためです。
4.3. サブクラスから
ここで、 FirstClassを拡張するクラスを宣言したが、別のパッケージで宣言した場合に何が起こるかを見てみましょう。
public class SecondClass extends FirstClass {
public SecondClass(String name) {
super(name);
System.out.println("SecondClass name is " + this.getName());
this.name = "new name";
}
}
予想どおり、すべての保護されたフィールド、メソッド、およびコンストラクターにアクセスできます。 これは、SecondClassがFirstClassのサブクラスであるためです。
5. 保護されたインナークラス
前の例では、 protected フィールド、メソッド、およびコンストラクターが動作しているのを見ました。 もう1つの特定のケースがあります—保護された内部クラスです。
FirstClass内にこの空の内部クラスを作成しましょう。
package com.baeldung.core.modifiers;
public class FirstClass {
// ...
protected static class InnerClass {
}
}
ご覧のとおり、これは静的な内部クラスであるため、FirstClassのインスタンスの外部から構築できます。 ただし、保護されているであるため、インスタンス化できるのはFirstClassと同じパッケージのコードからのみです。
5.1. 同じパッケージから
これをテストするために、GenericClassを編集してみましょう。
public class GenericClass {
public static void main(String[] args) {
// ...
FirstClass.InnerClass innerClass = new FirstClass.InnerClass();
}
}
ご覧のとおり、GenericClassはFirstClassと同じパッケージに含まれているため、InnerClassを問題なくインスタンス化できます。
5.2. 別のパッケージから
SecondGenericClassからInnerClassをインスタンス化してみましょう。これは、覚えているように、FirstClass’パッケージの外部にあります。
public class SecondGenericClass {
public static void main(String[] args) {
// ...
FirstClass.InnerClass innerClass = new FirstClass.InnerClass();
}
}
予想どおり、コンパイルエラーが発生します:
The type FirstClass.InnerClass is not visible
5.3. サブクラスから
SecondClassから同じことを試してみましょう。
public class SecondClass extends FirstClass {
public SecondClass(String name) {
// ...
FirstClass.InnerClass innerClass = new FirstClass.InnerClass();
}
}
InnerClassを簡単にインスタンス化することを期待していました。 ただし、ここでもコンパイルエラーが発生しています。
The constructor FirstClass.InnerClass() is not visible
InnerClass宣言を見てみましょう。
protected static class InnerClass {
}
このエラーが発生する主な理由は、 保護されたクラスのデフォルトのコンストラクターは暗黙的に
これらすべての理由により、SecondClassはprotected InnerClassコンストラクターにアクセスできません。
でこの問題を解決し、SecondClassでInnerClassオブジェクトをインスタンス化できるようにする場合、パブリックコンストラクターを明示的に宣言できます。
protected static class InnerClass {
public InnerClass() {
}
}
これにより、コンパイルエラーが発生しなくなり、SecondClassからInnerClassをインスタンス化できるようになりました。
6. 結論
このクイックチュートリアルでは、Javaのprotectedアクセス修飾子について説明しました。 これにより、必要なデータとメソッドのみを同じパッケージ内のサブクラスとクラスに確実に公開できます。
いつものように、サンプルコードはGitHubでから入手できます。