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

Java构造函数内部的多态

华易安
2023-03-14
问题内容

码:

class A{

    A()  {
        test();
    }
    void test(){
        System.out.println("from A");
    }
}

class B extends A {

    void test() {

        System.out.println("from B");

    }

}

class C {

    public static void main(String args []){

        A a = new B();

        a.test();
    }
}

输出:

from B 
from B

为什么以这种方式打印?


问题答案:

当您在运行时调用多态方法时,Java使用特殊的数据结构来决定需要调用哪个类的方法。在构造对象时,即
在执行用户提供的任何构造函数和初始化程序代码之前,都会 建立此结构。

创建时A a = new B(),在输入的构造函数 之前 已准备好“何时test()调用,则需要调用A.test()B.test()
数据结构。由于此结构是为类准备的,因此即使调用代码在内部的构造函数中,它也指向。这就是为什么您看到两次打印的原因。
__A``B``B.test()``A``"from B"

但是请注意,尽管从技术上讲您的代码将执行您想要的操作,但从逻辑上来说,这是一个非常糟糕的决定。这段代码很烂的原因与初始化序列有关:想象一个test()依赖于B在构造函数中初始化的私有字段的方法,如下所示:

class B extends A {
    private final String greeting;
    public B() {
        greeting = "Hello";
    }
    void test() {
        System.out.println(greeting + " from B");
    }
}

人们会期望看到"Hello from B"被印刷。但是,您只会在第二个呼叫中看到它:在进行第一个呼叫时,greeting它仍然是null

这就是为什么您应该避免从构造函数内部调用方法重写的原因:它打破了方法已假定对象已完全初始化的假设,有时会产生非常不幸的后果。



 类似资料:
  • 我有两个类:Date和Person Person有Date类的两个属性 案例1 类是与Person类分开的类。我有这段代码正常工作: 案例2:内部类(赋值要求) 我把作为Person的私有内部类 现在,上面的构造函数代码不再工作了。以下是错误消息: 说明资源路径位置类型由于某些中间构造函数调用人员,类型Person的封闭实例不可用。java/Wk03_Ch10_文件IO_Ch13_接口/Wk03_

  • 问题内容: 我有一堂课。 在我的类方法中,我实例化该类,如下所示: 编译器将此代码转换为: 使用反射表明该类具有以下综合的构造函数: 由于该类是,因此编译器会将该构造函数添加到该类中,因此没有人可以实例化该类。但是很明显,该类应该能够实例化它,因此编译器添加了另一个包私有构造函数,后者又调用了私有构造函数。另外,由于package- private构造函数的名称中包含该名称,因此普通的Java代码

  • 问题内容: 我的代码中有内部类。我想授予对其实例的公共访问权限,但是只有外部类才可以创建此实例,就像在“私有”访问权限中一样。是否可以不做适当的小包装(或为每个这样的内部类创建公共接口)? (对不起,如果我的英语不好:P) 问题答案: 有可能的。将 内部类 声明为 public,但将其构造函数声明为private 。这样,您只能在封闭的类及其内部内部创建它,而不能从外部创建它。

  • 我想在构造函数中访问多个位置的状态值。当我在构造函数中输入console.log(this)时,我可以看到可以访问特定的值,但是当我输入console.log this.state时,我没有定义。 这就是我想象的工作方式(我想访问CSSValue中的状态): 但是,当我运行此代码: 然后我在控制台中得到这个: 但是当我将console.logconsole.log(this.state)它打印未定

  • 本文向大家介绍Java构造函数,包括了Java构造函数的使用技巧和注意事项,需要的朋友参考一下 构造函数与方法相似,但在以下方面有所不同。 它们没有任何返回类型。 构造函数的名称与类的名称相同。 每个类都有一个构造函数。如果我们未为类明确编写构造函数,则Java编译器将为该类建立默认构造函数。 每次创建一个新对象时,将至少调用一个构造函数。 一个类可以具有多个构造函数。 示例 输出结果

  • 问题内容: 我是AP Java学生,正在为考试做练习。我遇到了这个问题,但我不明白答案: 考虑以下类别: 执行以下代码后输出是什么: 正确答案是B *。有人可以向我解释方法调用的顺序吗? 问题答案: B构造函数被调用。B构造函数的第一条隐式指令是(调用超类的默认构造函数)。因此,调用了A的构造函数。A的构造函数调用,它调用java.lang.Object构造函数,该构造函数不输出任何内容。然后被称