子类实例调用父类protected方法报错,求原因及解决办法
问题分析与解决
报错原因
Java中protected权限的访问规则是:
- 同一类内部可访问
- 同一包内的任意类可访问
- 子类内部可访问父类的
protected成员,但子类所在的其他外部类(比如你的test2),不能通过子类实例直接调用父类的protected方法
你的场景里,test2和H同属pkg.subpkg2包,但test2并不是restaurant的子类。虽然H继承了restaurant的open()方法,但在test2中通过H的实例调用open(),本质是试图在非子类、非同包(和父类restaurant不同包)的类中访问父类的protected成员,这违反了Java的权限规则,所以触发报错。
解决方案
方案1:在子类H中重写open()并改为public权限
修改H.java:
package pkg.subpkg2; import pkg.subpkg1.restaurant; public class H extends restaurant { @Override public void open() { super.open(); // 复用父类的实现逻辑 } }
修改后test2中可以直接调用r1.open(),因为此时open()在H中是public权限。
方案2:在H中添加包装方法间接调用父类open()
如果不想修改open()的权限范围,可以在H中新增一个public方法,内部调用父类的protected方法:
package pkg.subpkg2; import pkg.subpkg1.restaurant; public class H extends restaurant { public void triggerOpen() { open(); // 子类内部可合法访问父类的protected方法 } }
同时修改test2.java的调用逻辑:
package pkg.subpkg2; public class test2 { public static void main(String[] args) { H r1 = new H(); r1.triggerOpen(); // 调用包装方法触发父类逻辑 System.out.println(r1.name); } }
方案3:将restaurant的open()改为public权限
如果业务允许开放该方法的访问范围,直接修改restaurant.java:
package pkg.subpkg1; public class restaurant { public String name = "Domino"; public void open() { // 改为public权限 System.out.println("The restaurant is open"); } }
这种方式最简单,但会扩大方法的访问范围,需要根据实际业务需求判断是否适用。
内容的提问来源于stack exchange,提问作者AMITESH
相关产品推荐
相关产品推荐

