protected访7问修饰符表示如果两个类在同一个包中,那么被修饰为protected方法或属性可以被其它的类所访问。
但是如果两个类不在同一个包中,被修饰为protected的类只能被有继承关系的类(子类)所访问;没有继承关系的类不能访问。
public (友好)是限制级最小的,只要被修饰为public ,不管是不是同一个包,或者同一个类,有没有继承关系都可以被访问。
一般来说 访问控制分4种级别:
公开:public 同类 同包 子类 不同包 都可以访问
默认:只向同包同类放开
私有:private 只有类本身可以访问
保护:protected 向子类以及同一个包中的类放开
来看一下在该节中的例子
先定义一个ClassA 并把它放在mypack1包中
package mypack1;
public class ClassA {
public int var1;
protected int var2;
int var3;
private int var4;
public void method(){
var1=1;
var2=1;
var3=1;
var4=1;
ClassA a = new ClassA();
a.var1=1;
a.var2=1;
a.var3=1;
a.var4=1;
}
}
然后又在另外一个包 mypackage2中 存在ClassA的一个子类 ClassC
package mypack2;
import mypack1.ClassA;
class ClassC extends mypack1.ClassA{
public void method(){
ClassA a = new ClassA();
a.var1=1;
a.var2=1; //此行出错
}
}
实际上这个例子有问题
你会看到ide(或者编译时)在 a.var2=1 这一行报错 提示不能访问protected对象
这就是protected经常被人忽视的地方
尽管ClassC是ClassA的一个子类
但是在ClassC中创建的是ClassA的一个实例
该实例中的protected成员变量则很明显没有被ClassC继承到
自然在ClassC中无法访问var2
所以对于这种情况 将代码改为如下,则可以编译通过。
package mypack2;
import mypack1.ClassA;
class ClassC extends mypack1.ClassA{
public void method(){
ClassA a = new ClassA();
a.var1=1;
super.var2=1;
ClassC c = new ClassC();
c.var1=1;
c.var2=1;
}
}
OK,用java in a nutshell中的一段话来总结一下全文:
protected access requires a little more elaboration. Suppose class A declares a protected field x and is extended by a class B, which is defined in a different package (this last point is important). Class B inherits the protected field x, and its code can access that field in the current instance of B or in any other instances of B that the code can refer to. This does not mean, however, that the code of class B can start reading the protected fields of arbitrary instances of A! If an object is an instance of A but is not an instance of B, its fields are obviously not inherited by B, and the code of class B cannot read them.