protected 访问权限是这么定义的:protected 修饰的类和属性,对于本类、本包及其子类可见。
其实,protected受访问保护规则是很微妙的。
但可以概括为:
1、protected的方法在自己的包中与public相同,可容易访问。
对于实例方法来说:
2、对于不同包的父类与子类,只能通过自身实例(自身的引用)访问自身继承的实例方法,而不能通过父类实例(引用)访问父类的实例方法。
3、对于同父类的亲兄弟类,子类只能在自己的作用范围内,访问自己继承的那个父类的protected实例方法域,而无法到访问其他子类(同父类的亲兄弟类)所继承的protected实例方法域。
对于静态方法来说:
4、只要有继承关系(父类 或 同父类的亲兄弟类),都可以相互访问protected静态方法域。
下面将分别对易混的第二、三、四点进行阐述:
第二点(实例方法、不同包的父类与子类):
package A;
public class test{
protected void SOUT(){
System.out.println(100);
}
}
package B;
import A.*;
public class test2_1 extends test{
public static void main(String[] args) {
test aa = new test();
test2_1 bb = new test2_1();
aa.SOUT(); //编译不通过,不能通过父类实例(引用)访问父类的实例方法。
bb.SOUT(); //编译通过
}
}
第三点:
package A;
public class test{
protected void SOUT(){
System.out.println(100);
}
}
package B;
import A.*;
public class test2_1 extends test{
public static void main(String[] args) {
test2_2 aa = new test2_2();
aa.SOUT(); // 编译错误,因为这里的aa访问的是test2_2类的SOUT方法域,不行。
//但下列代码可以,因为访问的是自己的SOUT方法域。
test2_1 bb = new test2_1();
bb.SOUT();
}
}
class test2_2 extends test{
public static void k(){
test2_2 aa = new test2_2();
aa.SOUT(); // 在这里访问就可以,因为访问的是本类的SOUT方法域。
}
}
第四点:
package A;
public class test{
protected static void SOUT(){
System.out.println(100);
}
}
package B;
import A.*;
public class test2_1 extends test{
public static void main(String[] args) {
test aa = new test();
aa.SOUT();
test2_1 bb = new test2_1();
bb.SOUT();
test2_2 cc = new test2_2();
cc.SOUT();
//均编译通过,因为protected修饰的是静态方法,
//可以任意访问 父类 或 同父类的亲兄弟类 的SOUT方法
}
}
class test2_2 extends test{
}
正因如此,我们无法在我们的类中直接调用 anObject.clone(); 。