为什么从基类调用方法调用子方法?
我是学生,学习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
。但我仍然不明白为什么会出现问题。
作为达科他回答,根本原因是polymorphism
。这意味着我们可以创建子对象,但将它们称为它们的父类型,并且当我们调用父层的方法时,我们实际上会引用子对象的方法。
在我的情况下,我创建了一个子对象(标记为//第一个)B
,它有自己的initialize
方法的主体。继承的一个细微差别是它不包含构造函数,所以我可以调用父类的构造函数(标记为//第二个)。在父类的构造函数中,我调用initialize
方法 - 这就是多态,因为我从其父抽象层调用子方法。
这里是问题的答案 - 出现这种情况,因为我们只为B
实例分配的内存,这意味着,我们采取了A
作为我们基地,并开始扩展它(尽管我们可以在里面覆盖任何东西)。我们做的只有两两件事是:
- 我们创建了一个构造函数(这是不包括在基地,如上所述)
- 我们覆盖了
initialize
方法的代码。此对象现在丢失了位于基数内的此方法的代码。
的polymorphism
这个概念就是这样设计的,有没有办法让我们访问这个基地方法,除非我们专门创建一个对象,要么是A
本身或不覆盖此方法的孩子。
你试图做的是打败多态的目的。你可以,但你必须专门打电话。给你的方法添加一个布尔值,并调用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");
}
}
}
我认为这只是调用覆盖的方法,因为你是从覆盖它的类调用超类,所以它总是会使用这个方法从B类? –
这是整个重写... –