假设我们有两个软件包p1p2,以及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()的编译错误:
java - 为什么在同一包装中看不到包装保护方法?-LMLPHP

我的问题是:为什么在method1包中受包保护的p1在同一个A包的p1类中不可见?

最佳答案

首先,什么是班级成员? Java Language Specification状态

类主体可以包含类成员的声明,即
是,字段(§8.3),方法(§8.4),类(§8.5)和接口
(第8.5节)。

它们由什么组成? JLS states

类类型的成员包括以下所有:


  • 成员从其直接超类(第8.1.4节)继承了,但在Object类中没有直接超类
  • 从任何直接超级接口(第8.1.5节)继承的成员
  • 在类(第8.1.6节)中的成员声明


  • 它还提到

    只有声明为protectedpublic的类的成员才是
    由包中声明的包中的子类继承,而不是
    该类被声明。

    所有这些都在chapter on Inheritance中改写了

    C继承其直接超类所有具体方法m (静态和实例)超类的所有
    以下是正确的:


  • mC的直接超类的成员。
  • mpublicprotected,它们在与C` 相同的包中具有包访问权限声明。
  • C中声明的方法没有签名是m签名的子签名(第8.4.2节)。

  • M1类的成员是method1(以及Object的所有方法)。 M12与它的直接超类M1位于不同的包中,不继承method1。因此,M12的成员只是method2
    B的直接超类是M12,并且在同一包中。因此,它继承了其成员method2Bmethod1一无所知。如果您使用javac编译了代码,则将收到cannot find symbol编译错误。 (看来Eclipse试图猜测您要做什么。)

    同样,A的直接超类是M12,但是在不同的包中。因此,它不继承method2A不了解method1method2,因为它没有继承它们。这两个都是找不到的符号。

    07-24 15:00