跨包的子类只能通过自身或子类实例(如this、new Child())访问继承的protected成员,禁止通过父类引用(如Parent p = new Child(); p.field)访问,本质是继承可见性控制而非跨包开放。

跨包的子类可以访问父类的 protected 成员,但**仅限于通过子类自身对象(或其子类对象)来访问,不能通过父类类型引用访问**。这是 Java 中 protected 访问修饰符的关键规则。
protected 的实际访问范围
protected 成员对以下情况可见:
- 同一包内的所有类(无论是否继承)
- 不同包中的子类(必须是继承关系,且只能通过“本类实例”访问)
注意:它不等于“对子类公开”,而是“对子类及其后代的实例方法中可访问”。访问主体必须是当前正在执行的子类实例本身。
能访问的写法(正确示例)
假设父类 Animal 在 com.example.base 包中:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
package com.example.base;
public class Animal {
protected String name = "unknown";
protected void breathe() {
System.out.println("breathing...");
}
}
子类 Dog 在 com.example.pet 包中:
package com.example.pet;
import com.example.base.Animal;
public class Dog extends Animal {
public void show() {
System.out.println(name); // ✅ 正确:直接访问继承来的 protected 字段
breathe(); // ✅ 正确:直接调用继承来的 protected 方法
this.name = "Buddy"; // ✅ 正确:通过 this(即当前 Dog 实例)访问
}
}
不能访问的常见错误(编译报错)
以下写法在跨包子类中会编译失败:
- 通过父类引用访问子类继承的
protected成员 - 在静态上下文中直接访问(
protected不是静态可见性) - 通过其他同包/不同包子类的实例去访问(非当前类实例)
public class Dog extends Animal {
public void badExample(Animal a) {
System.out.println(a.name); // ❌ 编译错误:a 是 Animal 类型引用,跨包不可见
a.breathe(); // ❌ 同样错误:不能通过父类引用调用
}
public static void staticMethod() {
// System.out.println(name); // ❌ 静态方法中不能访问非静态 protected 成员
}
}
为什么这样设计?
Java 的 protected 本质是“继承友好型访问控制”,目的是支持子类扩展父类行为,同时防止外部随意通过父类引用来破坏封装。它强调的是身份归属:只有“我(当前子类实例)拥有的那个受保护成员”才能被我用,而不是“只要是父类的 protected,谁拿到引用都能用”。

















