同包不同类时default和protected均可见,不同包子类仅能访问继承的protected成员而不可访问default成员。关键在先判包再判继承,跨包时default彻底失效,protected仅限子类自身调用。

掌握 Java 访问权限控制中“同包不同类”与“不同包子类”的边界差异,关键在于理解 包可见性 和 继承可见性 的叠加逻辑,而不是死记表格。这两类场景最容易混淆的点,恰恰集中在 protected 和 default(即包访问权限)的行为分界上。
同包不同类:只看“包”,不看“继承”
只要两个类在同一个包里,不管有没有继承关系,它们对彼此成员的访问能力完全一致——private 不可见,其余三种(default、protected、public)都可见。
-
default成员:同包内任何类(包括普通类、子类、无关类)都能直接调用 -
protected成员:在同包下,它和default实际效果一样——子类能访问,非子类也能访问 - 注意:
protected在同包中“降级”为包级可见,并不强制要求通过继承访问
不同包子类:必须同时满足“包外”+“继承”两个条件
当子类和父类不在同一包中时,protected 才真正体现其设计本意;而 default 则彻底失效。
-
protected成员:子类可以访问——但仅限于访问自己继承来的成员,不能通过父类实例去访问 - 举例:假设
Father在pkg1中定义了protected void go(),Son在pkg2中继承它。那么new Son().go()合法,但new Father().go()编译报错 -
default成员:跨包后完全不可见,即使有继承关系也不行
快速判断口诀
遇到访问问题,先问自己两个问题:
立即学习“Java免费学习笔记(深入)”;
- 这两个类是不是同一个包?→ 是:看修饰符是否为
private;否:继续问下一个 - 访问方是不是被访问方的子类,且跨包?→ 是:只有
protected和public可用;否:只剩public
实际编码中容易踩的坑
最常见的误用发生在跨包子类里试图用父类引用调用 protected 方法,或者误以为 default 在子类中自动“升级”为可继承。
- 错误写法:
Father f = new Son(); f.protectedMethod();→ 编译失败(不是Son自己调用) - 正确写法:
new Son().protectedMethod();或在Son类内部用super.protectedMethod() -
default字段或方法:子类无法继承,也无法重写,跨包后连编译都过不了


















