protectedアクセス修飾子は、クラスのメンバーを同じパッケージ内で、または他のパッケージにいるすべてのサブクラスで可視にします。
他の修飾子との違い:
private — 現在のクラス内のみアクセス可能protected — 現在のパッケージ内およびパッケージ外の子孫にアクセス可能public — どこからでもアクセス可能例:
package com.example.base; public class Parent { protected void sayHello() { System.out.println("Hello from parent"); } } package com.example.child; import com.example.base.Parent; public class Child extends Parent { public void tryHello() { sayHello(); // アクセスあり! } } public class NotChild { public void fail(Parent p) { // p.sayHello(); // エラー:アクセス不可 } }
外部クラス(継承していないクラス)が別のパッケージの
protectedメソッドに、そのクラスのオブジェクトを持ってアクセスできますか?
回答: いいえ、別のパッケージのprotectedメソッドへのアクセスは、サブクラスのみに許可されており、thisまたはサブクラスのオブジェクトへの参照を介してのみ行えます。
Parent p = new Child(); p.sayHello(); // エラー! ((Child) p).sayHello(); // 成功(Child内部で参照する場合)
物語
大規模なモジュールプロジェクトで、開発者が重要なビジネスメソッドを
protectedセクションに配置し、他のパッケージからはアクセスできないと思い込んでいました。別の開発者が同じパッケージ内でこれらのメソッドをテストで偶然使用し、その後のクラスの移動により予期しないアクセスエラーが発生しました。
物語
マイクロサービスプロジェクトで、protectedアクセスを持つメソッドを別のパッケージ内の親型への参照から呼び出そうとしましたが、呼び出しが機能しませんでした。これにより、スコープの誤解に基づいて、システム拡張メカニズムの一部で障害が発生しました。
物語
オープンソースライブラリで、protectedフィールドが不注意に使用され、あまりにも多くのクラスからアクセス可能となりました。これにより、オブジェクトの内部状態が偶然に破損し、サードパーティのアプリケーションで問題が発生しました。