父类的私有成员在子类中完全不可见、不可继承、不能直接访问,编译器不将其纳入子类符号表;必须通过父类提供的protected getter/setter或方法间接访问,严禁反射强行访问。

父类的私有成员(字段或方法)在子类中完全不可见、不可继承、也不能直接访问。这不是权限“不够”,而是语言层面的硬性隔离:编译器在编译子类时根本不会把父类的 private 成员纳入符号表,所以任何形如 this.field、super.field 或 super.method() 的写法都会报错,比如 “cannot resolve symbol” 或 “is private within this context”。
必须通过父类提供的受控接口间接访问
父类若需让子类使用其私有数据,应主动暴露安全、稳定的访问路径。常见做法包括:
- 在父类中声明
protected或public的 getter/setter 方法,子类调用这些方法读写私有字段 - 将核心逻辑封装成
protected方法(可带默认实现),供子类复用或重写 - 避免把字段本身设为
public或protected—— 这等于放弃封装,使子类与内部实现强耦合
C++ 中 protected 是标准解法
C++ 不允许子类访问父类 private 成员,但允许改为 protected:
-
protected成员对子类可见,且仅限于继承链内使用(外部对象不能通过点号直接访问) - 子类成员函数中可直接使用
this->x或x访问基类的protected字段 - 注意:
Base b; b.x;是非法的——protected不代表“半公开”,只允许在派生类自身逻辑中通过this或隐式基类子对象访问
Java 中不能靠修饰符“降级”,只能靠设计协作
Java 没有类似 C++ 的 protected 字段“开放给子类”的捷径。即使子类和父类同包,private 依然不可见。正确做法是:
- 父类提供
protected的 setter/getter(比public更克制,限制外部随意调用) - 子类在构造器或方法中调用这些方法,而非试图绕过封装
- 严禁在子类中用反射强行访问(
setAccessible(true))——JDK 17+ 默认拒绝,且破坏设计契约
常见误区要避开
以下说法都不成立:
- “子类继承了
private成员,只是不能访问” → 错。不参与继承,子类字节码里根本没有该字段/方法的引用 - “用
super()能访问父类私有字段” → 错。super()只调用父类构造器,不打开访问通道 - “子类定义同名字段就是覆盖父类
private” → 错。这是全新声明,与父类无任何关系(不隐藏、不重写)

















