假设我们有两个软件包p1
和p2
,以及p1.M1
扩展的p2.M12
类,如下所示:
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");
}
}
让我们用
M12
扩展p2.B
:package p2;
public class B extends M12 {
public void doSomething() {
method1();
method2();
}
}
这会产生编译错误,即
method1
,在p1
中不可见受p2
包保护的软件包。 method2
可见,没有问题。现在让我们用
p2.M12
扩展p1.A
:package p1;
import p2.M12;
public class A extends M12 {
public void doSomething() {
method1();
method2();
}
}
在这里,我收到
method2()
(可以理解)和method1()
的编译错误:我的问题是:为什么在
method1
包中受包保护的p1
在同一个A
包的p1
类中不可见? 最佳答案
首先,什么是班级成员? Java Language Specification状态
类主体可以包含类成员的声明,即
是,字段(§8.3),方法(§8.4),类(§8.5)和接口
(第8.5节)。
它们由什么组成? JLS states
类类型的成员包括以下所有:
它还提到
只有声明为
protected
或public
的类的成员才是由包中声明的包中的子类继承,而不是
该类被声明。
所有这些都在chapter on Inheritance中改写了
类
C
从继承其直接超类所有具体方法m
(静态和实例)超类的所有以下是正确的:
m
是C
的直接超类的成员。 m
是public
,protected
或,它们在与C` 相同的包中具有包访问权限声明。 C
中声明的方法没有签名是m
签名的子签名(第8.4.2节)。 M1
类的成员是method1
(以及Object
的所有方法)。 M12
与它的直接超类M1
位于不同的包中,不继承method1
。因此,M12
的成员只是method2
。B
的直接超类是M12
,并且在同一包中。因此,它继承了其成员method2
。 B
对method1
一无所知。如果您使用javac
编译了代码,则将收到cannot find symbol
编译错误。 (看来Eclipse试图猜测您要做什么。)同样,
A
的直接超类是M12
,但是在不同的包中。因此,它不继承method2
。 A
不了解method1
或method2
,因为它没有继承它们。这两个都是找不到的符号。