java - 继承 : Unexpected Output from return statement

标签 java inheritance

我正在参加 Java 认证的模拟测试并得到了这个问题:

What will the following code print?

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 bb = (Beta) b;  
        System.out.println(bb.h + "   " + bb.getH());  
    }  
}  

这是答案:
测试版 44 4 44
测试版 44 44 44

我的问题:为什么返回主类的 4 而不是子类的 44?它不应该返回 44 吗?

我也没有看到任何变量被范围更近的同名变量覆盖。

(抱歉我的英语不好。我说的是法语。)

最佳答案

这是因为Beta.hBaap.h是不同的字段。在b.h中,Baap.h被调用(即4),bb.hBeta.h被调用称为(即 44)。不同之处在于 b.getH() 调用 Beta.getH()(因为 b 是 new Beta())但正在读取 Baap.h 字段,而 bb.getH() 调用 Beta.getH()

看一下 main() 方法:

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());
        /* The string concatenation gets compiled to:
         * new StringBuffer().append(b.h).append("    ").append(b.getH()).toString();
         *                             \ This is Baap.h         \ This prints Beta 44 and returns 44 from Beta.h
         */
        // Printed "Beta 44" from b.getH().
        // Printed "4    44" from statements concatenation.
        Beta bb = (Beta) b;  
        System.out.println(bb.h + "   " + bb.getH());
        /* The string concatenation gets compiled to:
         * new StringBuffer().append(bb.h).append("    ").append(bb.getH()).toString();
         *                             \ This is Beta.h          \ This prints Beta 44 and returns 44 from Beta.h
         */
        // Printed "Beta 44" from b.getH().
        // Printed "44    44" from statements concatenation.
    }
}

From the Oracle JavaTM Tutorials - Inheritance, it was written that:

What You Can Do in a Subclass

  • The inherited fields can be used directly, just like any other fields.
  • You can declare a field in the subclass with the same name as the one in the superclass, thus hiding it (not recommended).
  • You can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it.
  • You can declare new fields in the subclass that are not in the superclass.

阅读更多:

关于java - 继承 : Unexpected Output from return statement,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25093245/

相关文章:

javascript - javascript继承之间的区别

从路径列表中表示文件系统(文件/目录)的 Java 树

java - 为什么在 Eclipse 中使用 "step into"时,即使没有步骤过滤器,也不显示对构造函数的调用

java - 在 C++ 中怎么说 != 0-9

java - 为什么父类(super class)分配给子类会出错?

c++ - 通过 QObject 子类实现多重继承的最接近解决方案

java - 重载子类的构造函数

inheritance - 在 Kotlin 中扩展数据类

java - UUID.randomUUID() 与 SecureRandom

java - 在同一实例上调用 equals() 是否比在更改实例上更快?