我们创建了 2 个类:
public class Base {
protected void method() {
System.out.println("Base");
}
}
public class Main extends Base {
public static void main(String[] args) {
Base obj = new Main();
obj.method();
}
@Override
public void method() {
System.out.println("Main");
}
}
编译运行https://onlinegdb.com/ByPbAtxZP,输出:
主要的
现在我们将它们分发到不同的包中(我们不更改任何其他内容):
package package1;
public class Base {
protected void method() {
System.out.println("Base");
}
}
package package2;
import package1.Base;
public class Main extends Base {
public static void main(String[] args) {
Base obj = new Main();
obj.method();
}
@Override
public void method() {
System.out.println("Main");
}
}
尝试编译https://onlinegdb.com/SyCsAKxWw并出现错误
Main.java:8: error: method() has protected access in Base obj.method(); ^
为什么拆分成2个包后尝试调用基类的受保护方法时会出现编译错误?
毕竟,修饰符的描述protected
说
用访问修饰符标记的字段和方法
protected
将可见:
- 在与我们相同的包中的所有类中;
- 在从我们的类继承的所有类中。
是的,这似乎有点奇怪,而且很难解释。我将举一些例子来解释这种行为。首先,让我们这样做:
在这种情况下,我们在控制台中看到 Base Main(首先它执行超类方法,然后是继承类)。这清楚地表明我们可以引用父类的受保护方法。
现在让我们这样做:
在第一种情况下,对 Main obj = new Main() 的方法调用不会导致编译问题,而在第二种情况下,对于 Base obj1 = new Main() 我们会看到错误。
这可以通过受保护的方法在一个包中和继承人可用这一事实来解释(这可以在第一个示例中看到,我们从另一个包中调用超类方法)。在第二个示例中,我们不调用超类方法,而是调用超类变量上的方法(Base obj1 = new Main(); obj1.method(); - 其中 obj1 是超类类型的变量)。这就是问题所在。