java - 为什么包保护方法在同一个包中不可见?

标签 java package

假设我们有两个包 p1p2 以及由 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() 均出现编译错误: The method method1 from the type M1 is not visible

我的问题是:为什么 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 or public 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 methods m (both static and instance) of the superclass for which all of the following are true:

  • m is a member of the direct superclass of C.
  • m is public, 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 of m.

M1 类的成员是method1(以及Object 的所有方法)。 M12 与其直接父类(super class) M1 位于不同的包中,不继承 method1。因此M12的成员只有method2

B 的直接父类(super class)是 M12 并且在同一个包中。因此它继承了它的成员method2Bmethod1 一无所知。如果您使用 javac 编译代码,您会收到一个 cannot find symbol 编译错误。 (看起来 Eclipse 正试图猜测您要做什么。)

同样,A 的直接父类(super class)是M12,但在不同的包中。由于这个原因,它不继承 method2Amethod1method2 一无所知,因为它没有继承它们。找不到这两个符号。

关于java - 为什么包保护方法在同一个包中不可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46717820/

相关文章:

java - 将泛型与 Jakarta 公共(public)集合缓冲区一起使用

python - 如何使用 twine 将新版本的项目上传到 PyPI?

java - 热图未以 fragment 形式显示

java - 为什么我的图像不显示在 jsp 中? [使困惑]

java - Google Guava getTopLevelClasses 返回空集

java - 如何在eclipse中导入同一项目中其他包中定义的类?

r - 在另一个包中包含 tidyverse 包

java - 声明的包测试与预期的包不匹配

一组值的 Java 验证方法

java - 使用 ArrayList 构造函数制作 List 的转换副本