我是学生,学习Java。我知道,protected
表示来自children
或the same package
的访问权限。在这里,我们继承并覆盖受保护的方法。在这样的动作之后,每当基类想要调用它自己的方法时,它就会从子类中调用新的被覆盖的方法。我已经调试了一段时间并用注释标记了执行顺序。但是当我从基类构造函数中清楚地调用它时,我无法理解它为什么不调用基本方法?
public class Solution {
public static void main(String[] args) {
new B(); // first
}
public static class A {
public A() {
initialize(); // third
}
protected void initialize() {
System.out.println("class A"); // we never go here
}
}
public static class B extends A {
public B() {
super(); // second
initialize(); // fifth
}
protected void initialize() {
System.out.println("class B"); // fourth, sixth
}
}
}
这是来自一个网站的任务,所以基本上解决方案是将initialize
方法的访问修饰符从protected
更改为private
。但我仍然不明白为什么会出现这个问题。
答案 0 :(得分:1)
你要做的是打败多态的目的。你可以,但你必须专门打电话。在方法中添加一个布尔值并调用super.initialize(Boolean)。同样,这会破坏多态性和扩展类HAS以了解超类。不是很优雅。
public class Solution {
public static void main(String[] args) {
new B(); // first
}
public static class A {
public static boolean USE_SUPER = true;
public A() {
initialize(USE_SUPER);
}
protected void initialize(boolean unusedHere) {
System.out.println("class A");
}
}
public static class B extends A {
public static boolean USE_EXTENDED = false;
public B() {
super();
initialize(USE_EXTENDED);
}
protected void initialize(boolean useSuper) {
if (useSuper)
super.initialize(useSuper);
else
System.out.println("class B");
}
}
}
答案 1 :(得分:0)
当 Dakoda 回答时,根本原因是polymorphism
。这意味着我们可以创建子对象,但是将它们称为父类型,当我们调用父层的方法时,我们实际上引用了子对象的方法。
在我的例子中,我创建了一个子对象(标记为// first)B
,它有自己的initialize
方法体。继承的一个细微差别是它不包含构造函数,所以我可以调用父的构造函数(标记为//秒)。在父的构造函数中,我调用initialize
方法 - 这是多态,因为我从其父抽象层调用子方法。
以下是问题的答案 - 这种情况发生了,因为我们只为B
实例分配了内存,这意味着我们将A
作为 base 并启动了扩展它(我们可以覆盖里面的任何东西)。我们做的唯一两件事是:
initialize
方法代码。现在,此对象的 base 中的此方法的代码已丢失。 polymorphism
这个概念就是这样设计的,除非我们专门创建一个A
本身的对象,否则我们无法访问 base 方法。一个不会覆盖这种方法的孩子。