假设我们有两个包 p1
和 p2
以及由 p2.M12
扩展的类 p1.M1
作为如下:
package p1;
public class M1 {
void method1() {
System.out.println("Method 1 called");
}
}
package p2;
import p1.M1;
public class M12 extends M1 {
void method2() {
System.out.println("Method 2 called");
}
}
让我们用 p2.B
扩展 M12
:
package p2;
public class B extends M12 {
public void doSomething() {
method1();
method2();
}
}
这会导致编译错误,因为 method1
,在 p1
中受包保护在 p2
中不可见。 method2
是可见的,没有问题。
现在让我们用p1.A
扩展p2.M12
:
package p1;
import p2.M12;
public class A extends M12 {
public void doSomething() {
method1();
method2();
}
}
在这里,method2()
(这是可以理解的)和 method1()
均出现编译错误:
我的问题是:为什么 p1
包中受包保护的 method1
在类 A
中不可见相同的包 p1
?
最佳答案
首先,什么是类的成员? Java Language Specification州
A class body may contain declarations of members of the class, that is, fields (§8.3), methods (§8.4), classes (§8.5), and interfaces (§8.5).
它们是由什么组成的? JLS states
The members of a class type are all of the following:
- Members inherited from its direct superclass (§8.1.4), except in class Object, which has no direct superclass
- Members inherited from any direct superinterfaces (§8.1.5)
- Members declared in the body of the class (§8.1.6)
还提到了
Only members of a class that are declared
protected
orpublic
are inherited by subclasses declared in a package other than the one in which the class is declared.
所有这些都在 chapter on Inheritance 中改写了
A class
C
inherits from its direct superclass all concrete methodsm
(both static and instance) of the superclass for which all of the following are true:
m
is a member of the direct superclass ofC
.m
ispublic
,protected
, or declared with package access in the same package as C`.- No method declared in
C
has a signature that is a subsignature (§8.4.2) of the signature ofm
.
M1
类的成员是method1
(以及Object
的所有方法)。 M12
与其直接父类(super class) M1
位于不同的包中,不继承 method1
。因此M12
的成员只有method2
。
B
的直接父类(super class)是 M12
并且在同一个包中。因此它继承了它的成员method2
。 B
对method1
一无所知。如果您使用 javac
编译代码,您会收到一个 cannot find symbol
编译错误。 (看起来 Eclipse 正试图猜测您要做什么。)
同样,A
的直接父类(super class)是M12
,但在不同的包中。由于这个原因,它不继承 method2
。 A
对method1
或method2
一无所知,因为它没有继承它们。找不到这两个符号。
关于java - 为什么包保护方法在同一个包中不可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46717820/