继承中意外的输出

时间:2017-01-18 10:58:13

标签: java

我从Java认证问题得到了一些代码,其输出类型令我感到困惑。这是代码

class Baap {
    public int h = 4;
    public int getH() {
        System.out.println("Baap " + h);
        return h;
    }
}

class Beta extends Baap {
    public int h = 44;
    public int getH() {
        System.out.println("Beta " + h);
        return h;
    }
    public static void main(String[] args) {
        Baap b = new Beta();
        System.out.println(b.h + " " + b.getH());
    }
}

输出结果为:

Beta 44
4 44

我原以为是:

4 Beta 44
44

为什么会产生这个输出?

4 个答案:

答案 0 :(得分:3)

System.out.println(b.h + " " + b.getH())可以打印任何内容之前,必须对b.h + " " + b.getH()进行评估。

b.getH()调用Beta方法(因为它覆盖基类方法),打印Beta 44

然后b.h(4)附加到b.getH()(44)的结果,println打印4 44

b.h返回基类(4)的h变量的值,因为b的编译时类型是Baap(基类),和变量不能被覆盖。另一方面,b.getH()返回子类(44)的h变量的值,因为可以覆盖方法。

答案 1 :(得分:3)

输出由两部分组成:

  1. getH()
  2. 内打印的一条线
  3. main()
  4. 内打印的一条线

    getH()生成的行在main()生成的行之前打印,因为getH()必须在main完成构造输出之前完成。

    现在输出应该清晰:即使在4内调用getH之前main 已评估,它也会被打印 getH()返回后。

答案 2 :(得分:1)

答案在JLS

  

15.7.2。在操作之前评估操作数

     

Java编程语言保证在执行操作本身的任何部分之前,操作符的每个操作数(条件运算符&&,||和?:)除外似乎都要完全评估。

您的方法getH()具有副作用,并且在调用该方法的表达式完全评估之前,可以观察

由于两个部分:

String baapBetaStr = b.h + " " + b.getH();

A)字符串连接

B)方法调用

当然,为了连接该字符串,需要首先评估该表达式的所有部分("运行")!

答案 3 :(得分:0)

%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns