无法访问具有超类引用的受保护实例变量,而能够访问具有超类引用的同一超类的受保护函数
package Test;
import Different.Exam;
public class Test {
protected int a = 4;
protected int add(int a, int b){
return a+b;
}
}
子类
package Different;
import Test.Test;
public class Exam extends Test {
protected void methodWithDefaultAccess(){
Exam exam = new Exam();
exam.add(1, 2);
System.out.println("A in super class is.. "+a);
System.out.println("A in super class is .." exam.a);
}
}
在这种情况下,我能够访问具有超类引用的受保护函数,但无法访问具有超类引用的实例变量。
如果问题是为什么将引用声明为Test exam = new Exam();
会使exam.a
无法访问,那么 Java 语言规范 (http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2) 指出:
受保护成员或构造函数可以从包外部访问,在该包中,它仅由负责实现该对象的代码声明(...)。设 C 是在其中声明受保护成员的类。只允许在 C 的子类 S 的主体内访问。此外,(...如果访问是通过字段访问表达式 E.Id(其中 E 是主表达式)或方法调用表达式 E.Id(. . .) 进行访问,其中 E 是主表达式,则当且仅当 E 的类型为 S 或 S 的子类时,才允许访问。
简单来说:从子类中,不能使用类型为父类的引用访问在父类中声明的受保护成员。引用的类型必须是子类(或其后代类)。