Java protected 关键字
作者:互联网
- 基类的 protected 成员是包内可见的,并且对其子类可见;
- 若子类 S 与基类 C 不在同一包中,那么在子类 S 中,只能访问 S 的实例及 S 的子类实例从基类 C 继承而来的 protected 成员。
以访问方法为例说明第二点:
// 示例一
package p1;
public class FatherInP1 {
protected void protectedMethod() {} // 父类 FatherInP1 中的 protected 方法
}
package p1;
public class Son1InP1 extends FatherInP1 {}
package p2;
public class Son2InP2 extends FatherInP1{}
package p1;
public class Test {
public static void main(String[] args) {
Son1InP1 son1InP1 = new Son1InP1();
son1InP1.protectedMethod(); // Compile OK ----(1)
son1InP1.clone(); // Compile Error ----(2)
Son2InP2 son2InP2 = new Son2InP2();
son2InP2.protectedMethod(); // Compile OK ----(3)
son2InP2.clone(); // Compile Error ----(4)
}
}
(1)(3):其中的 protectedMethod() 方法从类 FatherInP1 继承而来,其可见性是包 p1 及其子类(Son1InP1 和 Son2InP2),由于调用 protectedMethod() 方法的类 Test 所在的包也是 p1,因此 (1)(3) 处编译通过。
(2)(4):其中的 clone() 方法的可见性是 java.lang 包及其所有子类,对于语句 son1InP1.clone();
和 son2InP2.clone();
,二者的 clone() 在类 Son1InP1、Son2InP2 中是可见的,但对 Test 是不可见的(因为 Test 不在 java.lang 包下,只能够访问自身及其子类实例从 Object 类继承到的 clone 方法),因此 (2)(4) 处编译不通过。
// 示例二
package p1;
class FatherInP1 {
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
package p2;
public class SonInP2 extends FatherInP1 {
public static void main(String args[]) {
FatherInP1 fatherInP1 = new FatherInP1();
fatherInP1.clone(); // Compile Error ----(1)
SonInP2 sonInP2 = new SonInP2();
sonInP2.clone(); // Compile OK ----(2)
}
}
(1):clone() 方法来自于类 FatherInP1 本身,因此其可见性为包 p1 及 FatherInP1 的子类,虽然 SonInP2 是 FatherInP1 的子类,但在 SonInP2 中不能访问基类 FatherInP1 的 protected 方法 clone()(因为 SonInP2 不在 p1 包下,只能够访问其自身及其子类从 FatherInP1 类继承到的 clone 方法,而不能够访问 FatherInP1 实例及其他 FatherInP1 子类实例中受保护的 clone 方法),因此编译不通过。
(2):由于在 SonInP2 中访问的是其本身实例从基类 FatherInP1 继承来的的 clone(),因此编译通过。
// 示例三
package p1;
class SonInP1 extends FatherInP2 {
}
package p2;
public class FatherInP2 {
public static void main(String args[]) {
SonInP1 sonInP1 = new SonInP1();
sonInP1.clone(); // Compile OK ------(1)
}
}
(1):clone() 方法来自于 Object 类,其可见性为包 java.lang 及其子类,子类 FatherInP2 不在 java.lang 包下,能够访问其自身及其子类从 Object 类继承到的 clone 方法,(1)正是尝试在父类 FatherInP2 中访问其子类实例继承到的 clone 方法,编译通过。
// 示例四
package p1;
class SonInP1 extends FatherInP2 {
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package p2;
public class FatherInP2 {
public static void main(String args[]) {
SonInP1 sonInP1 = new SonInP1();
sonInP1.clone(); // Compile Error -----(1)
}
}
(1):clone() 方法来自于类 SonInP1,其可见性为包 p1 及其子类(此处没有子类),而类 FatherInP2 在包 p2 中且不是 SonInP1 的子类,因此不满足可见性,编译不通过。
// 示例五
package p1;
class FatherInP1 {
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
public class SonInP1 {
public static void main(String[] args) throws CloneNotSupportedException {
FatherInP1 fatherInP1 = new FatherInP1();
fatherInP1.clone(); // Compile OK ----(1)
}
}
(1):clone() 方法来自于类 FatherInP1,其可见性为包 p1 及其子类 (此处没有子类),而类 SonInP1 也在包 p1 中,因此满足可见性,编译通过。
// 示例六
package p1;
class SonInP1 extends FatherInP1{}
public class FatherInP1 {
public static void main(String[] args) {
SonInP1 sonInP1 = new SonInP1();
sonInP1.clone(); // Compile OK -------(1)
}
}
(1):clone() 方法来自于类 Object,其可见性为包 java.lang 包及其子类,子类 FatherInP1 不在 java.lang 包下,能够访问其自身及其子类从 Object 类继承到的 clone 方法,而(1)正是尝试在父类 FatherInP1 中调用其子类 SonInP1 继承到的 clone 方法,编译通过。
// 示例七
package p1;
class SonInP1 extends FatherInP1 {
public static void main(String[] args) {
FatherInP1 fatherInP1 = new FatherInP1();
fatherInP1.clone(); // Compile Error ----- (1)
}
}
public class FatherInP1 { }
(1):clone() 方法来自于类 Object,因此该 clone() 方法可见性为包 java.lang 及其子类,SonInP1 能够访问自身及其子类从 Object 继承到的 clone 方法,由于类 FatherInP1 不是 SonInP1 的子类,因此不满足可见性,编译不通过。
Demo 及主要内容来自 1,但其中的解释(至少对我来说)并不准确。
标签:p1,Java,FatherInP1,子类,clone,关键字,protected,SonInP1,public 来源: https://www.cnblogs.com/Higurashi-kagome/p/16171458.html