【问题标题】:Abstract Method called in its class's constructor在其类的构造函数中调用的抽象方法
【发布时间】:2016-08-20 07:25:33
【问题描述】:

我有抽象类 Shape 如下,其中包含抽象方法 calc -

public abstract class Shape{
   public Shape(){
       System.out.println("from shape");
       calc();
   }

public abstract void calc();
}

另一个类 Circle 扩展了 Shape -

public class Circle extends Shape{
 public Circle(){
    System.out.println("from Circle");
 }
     public void calc(){
        System.out.println("from calc in circle");
     }
}

现在是 Final 主类-

public class BasicsTest{
   public static void main(String [] args){
      Cirlce c=new Circle();
   }
}

运行主类时的输出 -

从形状

从圆圈中计算

来自圈子

我知道当我们创建子类的对象时,会调用父类的构造函数。我很困惑的是在 shape 的构造函数中调用 calc 方法是如何工作的,因为我们没有 shape 类中的 calc 实现。

      public Shape(){
       System.out.println("from shape");
       calc();  // how the method from child class is being called ??
   }

从输出看来,它似乎是从子类 circle 调用覆盖的 calc 方法,但它是如何工作的?

谢谢。

【问题讨论】:

标签: java class abstract


【解决方案1】:

这就是多态性和继承的工作原理。如果要编写面向对象的代码,理解它很重要。

最简单的解释是想象有一个方法表,上面写着“我知道我在编译时是一个抽象类,但在运行时我知道我是一个具体的子类。查找子类的方法表中的那个方法并调用它。”在运行时会进行一定程度的间接测量。

【讨论】:

    【解决方案2】:

    把它想象成对this.calc() 的调用。它不调用同一个类的calc方法,而是调用thiscalc方法,this > 是一个圆形对象。

    【讨论】:

    • 如果您查看程序输出,它看起来像是在最后调用了 Circle 构造函数。因此,当调用 calc 方法时,此时没有可用的或创建的 Circle 对象(或 this)。所以不确定 this.calc() 是否有效?
    【解决方案3】:

    您在测试中实例化一个 Circle 类。

    那么在您的 Circle 实例中发生了什么:

    • 循环构造函数被调用
    • 调用了超级构造函数
    • 超级构造函数调用 calc() 方法
    • Circle(!) 实例的 calc() 方法被调用

    请注意,您没有实例化一个 Shape 而是一个圆。关键部分是真正理解方法覆盖在 OO 中是如何工作的: calc() 方法实际上只是指向实际实现的虚拟指针。 由于您正在实例化一个 Circle,这将指向您的 Circle 类中的覆盖实现

    【讨论】:

    • 但是如果您查看输出,程序流程如下所示- 01) 调用形状构造函数 02) 调用 Circle 类中的 calc() 方法(这里我假设尚未创建圆形对象仍然可以从 Circle 类中调用方法!!) 03)调用 Circle 构造函数
    • 可能看起来像这样,但实际上并非如此。 super() 构造函数调用将在您的 System.out.println("from Circle") 之前隐式调用。所以它去 Circle() -> Shape() -> (在 Shape 构造函数中执行东西) -> 返回并继续在圆形构造函数中执行东西 当你进入构造函数时你的实例已经到位。这就是您可以通过“this”访问成员和方法的原因
    【解决方案4】:

    Jon skit 和 Eyal Schneider 在以下帖子中的答案可能是这个问题的答案-

    State of Derived class object when Base class constructor calls overridden method in Java

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-14
      • 1970-01-01
      • 2020-06-18
      • 2019-04-19
      • 1970-01-01
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多