默认的时候可以被同一类和它的子类访问,同一包和其他包中的类不可以访问;
protected可以被同一类、子类和同一包中的类访问,其他包中的类不可以访问;
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.
protected 访问需要格外小心。假定一个类A声明了一个protected 的域x,A被B继承,B被定义在一个不同的包中。 类B继承了这个保护域x,在B的当前实例中或者在B的任何实例中,它的代码是可以访问x的。但这并不表明B可以访问任何A的实例的protected域,如果一个对象是A的实例,但不是B的实例,那么它的域就没有被B继承,类B的代码也就不能访问它。
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
import mypack1.ClassA;
class ClassC extends mypack1.ClassA ... {
public void method()...{
ClassA a = new ClassA();
a.var1=1;
a.var2=1; //此行出错
}
}
在出错那一行,变量var2是具有protected的,ClassC 可以访问从父类继承的ClassA的protected域,但是不能用ClassA的实例访问它。下面的代码演示了如何使用var2:
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;
}
}
super.var2访问就是从父类继承来的protected变量,而因为c是ClassC的实例,并且在ClassC的代码中调用,是可以的,c这个对象如果放在其他的类中,它依然不能访问var2。