当前位置: 首页 > 面试题库 >

试图掌握继承问题

公冶龙野
2023-03-14
问题内容

鉴于Main.java:

public class Main{
    public static void main(String[]args){
          A a = new B();
          a.print();
    }

}

class A{
       A() {print();}
       void print() { System.out.println("A"); }
}

class B extends A{
       int i = 4;
       void print() { System.out.println(i); }
}

结果为:
0
4.
但是,如果a.print输出引用A类,为什么为什么不输出“ A”呢?我怎么知道在这种情况下何时调用一种方法?为什么要调用A的构造函数而仍然使用B的方法?


问题答案:

由于多态性而调用a.print()打印。调用的方法取决于的运行时类型,即。何时调用无关紧要;多态总是适用。4a``B

两次都调用Bprint方法。一次来自A的构造函数,由中的默认构造函数调用B。另外一次是您显式致电main

究其原因,第一印刷产量0,而不是4因为在那个时候print被调用时,A仍在建设。也就是说,A构造函数仍在执行。在超类构造函数返回之前,子类中尚未初始化任何东西,甚至变量初始化器也没有初始化。该值4在超类构造函数完成之后但在其余子类构造函数完成之前分配。由于变量初始值设定项尚未运行,因此默认值0(将false用于booleans和null对象)是i第一次打印时的值。

JLS的第12.5节列出了此订单:

在返回对新创建对象的引用作为结果之前,使用以下过程处理指示的构造函数以初始化新对象:

  1. 将构造函数的参数分配给此构造函数调用的新创建的参数变量。

2.
如果此构造函数以同一个类中的另一个构造函数的显式构造函数调用(第8.8.7节)开头(使用此方法),则使用相同的五个步骤评估参数并递归处理该构造函数调用。如果该构造函数调用突然完成,则该过程由于相同的原因而突然完成;否则,请继续执行步骤5。

3.
此构造函数并不以对同一个类中的另一个构造函数的显式构造函数调用(使用此函数)开头。如果此构造函数用于Object以外的其他类,则此构造函数将以显式或隐式调用超类构造函数(使用super)开始。使用这五个相同的步骤来递归评估超类构造函数调用的参数和过程。如果该构造函数调用突然完成,则出于相同原因,此过程也会突然完成。否则,请继续执行步骤4。

  1. 执行 此类 的实例初始化器和实例变量初始化器
    ,并按照从左到右的顺序将实例变量初始化器的值在文本中显示在该类的源代码中,并将它们分配给相应的实例变量。如果执行这些初始化程序中的任何一个导致异常,则不会再处理其他初始化程序,并且该过程会因相同的异常而突然完成。否则,请继续执行步骤5。

  2. 执行此构造函数的其余部分。如果该执行突然完成,则出于相同原因,此过程也会突然完成。否则,此过程将正常完成。

(强调粗体)

这是为什么调用一个可以从构造函数中覆盖的方法不是一个好主意的示例。子类状态尚未初始化。



 类似资料:
  • Cocos Creator 为开发者提供了非常丰富的界面元素,帮助开发者快速的开发面板界面。 于此同时, 我们还为开发者提供了控件预览面板,方便开发者在使用控件时,查看控件的各种属性和这些属性对应的效果。 要打开控件预览窗口,仅需要在主菜单中选择 开发者 / UI Kit Preview。 目前界面元素包括: 控件 ui-button ui-checkbox ui-color ui-input u

  • 并尝试通过Hibernate使用策略连接实现继承,但当我使用此策略时,我收到异常: 奇怪的是,如果我选择另一个策略(单表或TABLE_PER_CLASS),错误不会出现

  • exVim 将会允许用户生成指定类的类继承图。这是由 ex-hierarchy 插件完成的. 当运行:Update命令后,exVim将会生成继承文件。这个文件将会从你的ctags生成信息里面提取继承信息。它记录 你工程中类的继承关系。 ex-hierarchy 插件在你输入一个类时将会解析这个继承文件,它将会生成一个 Graphviz点格式文件,然后使用Graphviz画一个.png格式的图片。

  • <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta http-equiv="X-UA-Compatible" content="IE=edge">     <meta name="viewport" content="width=device-width, initial-scale=1.0">

  • 一个xinitrc系统文件能用来启动一个X服务器。这个文件包含了相当多的if/then测试,就像下面这个文件的一个摘录展示的一样。 1 if [ -f $HOME/.Xclients ]; then 2 exec $HOME/.Xclients 3 elif [ -f /etc/X11/xinit/Xclients ]; then 4 exec /etc/X11/x

  • 问题内容: 我有三节课: 现在在我的主要职能中,我做这样的事情: 但这会产生2个编译时错误: 无法将A转换为fileHandler 无法将B转换为fileHandler 如果基类不是泛型的,那么我如何摆脱这些错误呢? 更新: 我的班级层次结构是: 调用函数的C类或 调用函数的D类。 C和D都从抽象类E派生。 现在,我应该如何在C和D以及E中定义这些功能: 我给出了以下内容: E: C: D: C,