Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么从基类调用方法会调用子方法?_Java_Overriding_Protected - Fatal编程技术网

Java 为什么从基类调用方法会调用子方法?

Java 为什么从基类调用方法会调用子方法?,java,overriding,protected,Java,Overriding,Protected,我是一名学生,正在学习Java。我知道,protected意味着从儿童或同一个包访问。这里我们继承并重写一个受保护的方法。在这样一个操作之后,每当基类想要调用它自己的方法时,它就会从子类调用新的重写方法。我已经调试了一段时间,并用注释标记了执行顺序。但我不明白,当我从基类构造函数内部清楚地调用基类方法时,它为什么不调用基类方法呢 public class Solution { public static void main(String[] args) { new B(

我是一名学生,正在学习Java。我知道,
protected
意味着从
儿童
同一个包
访问。这里我们继承并重写一个受保护的方法。在这样一个操作之后,每当基类想要调用它自己的方法时,它就会从子类调用新的重写方法。我已经调试了一段时间,并用注释标记了执行顺序。但我不明白,当我从基类构造函数内部清楚地调用基类方法时,它为什么不调用基类方法呢

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
。但我仍然不明白为什么会出现这种问题。

你试图做的是挫败多态性的目的。你可以,但你必须明确地打电话。向方法中添加一个布尔值,并调用super.initialize(布尔值)。同样,这会破坏多态性,扩展类必须了解超类。不太优雅

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");
     }
}

  }
正如Dakoda所回答的,根本原因是多态性。这意味着我们可以创建子对象,但将其作为父对象类型引用,当我们调用父层的方法时,实际上是引用子对象的方法

在本例中,我创建了一个子对象(标记为//first)
B
,它有自己的
initialize
方法体。继承的一个细微差别是它不包含构造函数,因此我可以调用父级的构造函数(标记为//second)。在父级构造函数中,我调用
initialize
方法-这是多态性,因为我从父级抽象层调用子级的方法

下面是问题的答案-这种情况发生了,因为我们只为
B
实例分配了内存,这意味着,我们以
a
为基础,开始扩展它(同时我们可以覆盖其中的任何内容)。我们只做了两件事:

  • 我们创建了一个构造函数(如上所述,它没有包含在基础中)
  • 我们重写了
    initialize
    方法代码。此对象的基址内此方法的代码现在丢失

  • 多态性的这个概念就是这样设计的,我们没有办法访问基本方法,除非我们专门创建一个对象,它要么是
    A
    本身,要么是不覆盖此方法的子对象。

    我认为它只是调用覆盖的方法,因为您是从类中调用super哪个重写了它,所以它总是从B类中使用这个方法?这就是重写…@SamKruglov的要点,如果A.initialize()与B.initialize()不同,为什么要使用多态性?用不同的方式称呼他们。A.初始化A()和B.初始化B()。哦,是的,我想我明白了。我们只创建了对象B,因此我们只有从这个角度来看的方法。从父级调用方法只意味着多态性。谢谢