我试图了解受保护成员在类中的行为。我有一个TopClass包含受保护整数的类pr。
班级:
package com.test;
import com.test.anotherpackage.SubClass1;
import com.test.anotherpackage.SubClass2;
import com.test.anotherpackage.SubClass3;
public class TopClass {
protected int pr;
void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
t.pr = 3;
s1.pr = 0;
s2.pr = 1;
s3.pr = 1;
}
}
还有另一个包com.test.anotherpackage有 3 个类SubClass1,SubClass2和SubClass3. 继承层次如下:
SubClass1 extends TopClassSubClass2 extends SubClass1SubClass3 extends SubClass2
子类1
package com.test.anotherpackage;
import com.test.TopClass;
public class SubClass1 extends TopClass {
void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
t.pr = 0; // Error because not in same package.
s1.pr = 0; //(1)
s2.pr = 1; // Does not throw an Exception. Why? (2)
s3.pr = 1; // (3)
}
}
子类2
package com.test.anotherpackage;
import com.test.TopClass;
public class SubClass2 extends SubClass1 {
void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
t.pr = 0; // Error because not in same package.
s1.pr = 0; // Throws Exception, why? (4)
s2.pr = 1; // (5)
s3.pr = 1; // Does not throw an Exception. Why?(6)
}
}
子类3
package com.test.anotherpackage;
import com.test.TopClass;
public class SubClass3 extends SubClass2 {
void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
t.pr = 0;
s1.pr = 0; // Not Visible (7)
s2.pr = 1; // Not Visible (8)
s3.pr = 1; // (9)
}
}
在上面的代码中,(1), (2), (3),(5)和(6)完美(9)地工作,没有任何可见性问题。但是(4), (7),(8)存在可见性问题。
根据JLS§6.6.2.1,
令 C 为声明受保护成员的类。只有在 C 的子类 S 的主体内才允许访问。
此外,如果 Id 表示实例字段或实例方法,则:
如果通过限定名称 Q.Id 进行访问,其中 Q 是 ExpressionName,则当且仅当表达式 Q 的类型是 S 或 S 的子类时才允许访问。
如果通过字段访问表达式 E.Id(其中 E 是 Primary 表达式)或通过方法调用表达式 E.Id(. . .)(其中 E 是 Primary 表达式)进行访问,则当且仅如果 E 的类型是 S 或 S 的子类。
我想在这里理解的是为什么if the type of the expression Q is S or a subclass of S会出现。是否有任何特定场景可以使此实施受益?任何相关的例子都将受到高度赞赏。我尝试在 SO 上查看它,但找不到可以解决我疑问的解释。