访问修饰符 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字段,这些字段对过多的类可用,导致意外损坏对象的内部状态,从而造成第三方应用的问题。