继承:return语句的意外输出

阿基里斯范

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

这是答案:
Beta 44 4 44
Beta 44 44 44

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

我也看不到任何变量被另一个具有相同名称且在范围上更近的变量所遮盖。

(对不起,我的英语。我是法语。)

单面体

这是因为Beta.hBaap.h是不同的字段。在中b.hBaap.h被称为(为4)和在中bb.hBeta.h被称为(为44)。区别在于b.getH()calls Beta.getH()(因为b为new Beta()),但在readBaap.h字段中,而bb.getH()calls则为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.
    }
}

从《Oracle JavaTM教程-继承》中写道:

您可以在子类中做什么

  • 继承的字段可以像其他任何字段一样直接使用。
  • 您可以在子类中声明一个与超类中的名称相同的字段,从而将其隐藏(不建议)。
  • 您可以在子类中编写一个新的实例方法,该方法具有与超类中的签名相同的签名,从而将其覆盖。
  • 您可以在子类中声明不在超类中的新字段。

阅读更多:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章