1. java protected修饰符说明
1.1 同包下
定义如下的类A;
package package1; //所在的包
public class A {
public int pub;
private int pri;
protected int pro;
int def;
public A(int pub, int pri, int pro, int def) {
this.pub = pub;
this.pri = pri;
this.pro = pro;
this.def = def;
}
protected void func_protected(){
System.out.println("func_protected in Class A");
}
}
定义如下类A_2
package package1; // 与类A在同一个包下
public class A_2 {
public static void main(String[] args) {
A a = new A(1,2,3,4);
a.func_protected(); // 同一个包下,可以访问 A 类的 protected 方法
System.out.println(a.pri); // 同一个包下,不可以访问 A 类的 private 属性 (不可见,编译出错)
System.out.println(a.pub); // 同一个包下,可以访问 A 类的 public 属性
System.out.println(a.def); // 同一个包下,可以访问 A 类的 default 属性
System.out.println(a.pro); // 同一个包下,可以访问 A 类的 protected 属性
}
}
1.2 不同包下
定义如下类 B
package package2; // 类B与类A在不同的包下
import package1.A;
public class B {
public static void main(String[] args) {
A a = new A(1,2,3,4);
System.out.println(a.pro); // 不同包且非子类 无法访问 protected属性(不可见)
a.func_protected();// 不同包且非子类 无法访问 protected方法(不可见,编译出错)
}
}
定义类A的子类B_2如下:
package package2; // 类B_2与类A在不同的包下
import package1.A;
public class B_2 extends A{ //类B_2 是A类的子类
public B_2(int pub, int pri, int pro, int def) {
super(pub, pri, pro, def);
this.func_protected(); //不同包内,子类实例可以访问自身继承的protected方法
}
public static void main(String[] args) {
A a = new A(1,2,3,4);
B_2 b = new B_2(1,2,3,4);
a.func_protected(); //不在同一个包内,子类不可以访问父类实例的 protected方法,编译错误;(不可见,编译出错 )
b.func_protected(); //不在同一个包内,子类实例可以访问自身继承的 protected方法,编译通过;
C c = new C(1,2,3,4); // 无论是否同包下,子类可以访问子类的子类实例的protected方法编译通过
c.func_protected();
}
}
如果再定义类C如下:
package package3; // 与B_2类同包或者不同包
import package1.A;
import package2.B_2;
public class C extends B_2 {
public C(int pub, int pri, int pro, int def) {
super(pub, pri, pro, def);
}
public static void main(String[] args) {
A a = new A(1,2,3,4);
B_2 b_2 = new B_2(1,2,3,4);
b_2.func_protected(); // 编译错误,父类 protected 对其不可见
}
}
总结:
-
子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
-
子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,子类不能访问基类实例的protected方法。但是子类实例可以访问其子类实例的protected 方法或属性。
说明: 当子类存在子类,则这个子类等价与基类,子类的子类等价与子类