Java 继承:return语句的意外输出

Java 继承:return语句的意外输出,java,inheritance,Java,Inheritance,我正在参加Java认证的实践测试,并得到了以下问题: 下面的代码将打印什么 这就是答案: 贝塔44 444 贝塔44 44 44 我的问题:为什么主类返回的4,而不是子类返回的44?它不应该回来吗 我也没有看到任何变量被范围更近的同名变量所隐藏 (对不起,我说英语。我说法语。)这是因为Beta.h和Baap.h是不同的字段。在b.h中,调用Baap.h(即4)和bb.h,Beta.h(即44)。不同之处在于b.getH()调用Beta.getH()(因为b是newbeta()),但正在读取Baa

我正在参加Java认证的实践测试,并得到了以下问题:

下面的代码将打印什么

这就是答案:
贝塔44 444
贝塔44 44 44

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

我也没有看到任何变量被范围更近的同名变量所隐藏


(对不起,我说英语。我说法语。)

这是因为
Beta.h
Baap.h
是不同的字段。在
b.h
中,调用
Baap.h
(即4)和
bb.h
Beta.h
(即44)。不同之处在于
b.getH()
调用
Beta.getH()
(因为b是
newbeta()
),但正在读取
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.
    }
}
根据该报告,有人写道:

在子类中可以做什么
  • 继承的字段可以像其他字段一样直接使用
  • 您可以在子类中声明一个与超类中的字段同名的字段,从而将其隐藏(不推荐)
  • 您可以在子类中编写一个新的实例方法,该子类具有与超类中相同的签名,从而覆盖它
  • 可以在子类中声明不在超类中的新字段
阅读更多:


    • 这是因为
      Beta.h
      Baap.h
      是不同的字段。在
      b.h
      中,调用
      Baap.h
      (即4)和
      bb.h
      Beta.h
      (即44)。不同之处在于
      b.getH()
      调用
      Beta.getH()
      (因为b是
      newbeta()
      ),但正在读取
      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.
          }
      }
      
      根据该报告,有人写道:

      在子类中可以做什么
      • 继承的字段可以像其他字段一样直接使用
      • 您可以在子类中声明一个与超类中的字段同名的字段,从而将其隐藏(不推荐)
      • 您可以在子类中编写一个新的实例方法,该子类具有与超类中相同的签名,从而覆盖它
      • 可以在子类中声明不在超类中的新字段
      阅读更多:


      那么你的问题是为什么
      b.h
      在以下情况下计算为
      4
      ,而不是
      44

          Baap b = new Beta();  
          System.out.println(b.h + "    " + b.getH());  
                             ^^^ why is this 4?
      
      原因是Java中没有数据多态性。尽管它们共享相同的名称,
      Baap.h
      Beta.h
      是独立的、不相关的字段

      当编译器解析
      b.h
      时,它查看
      b
      的静态(即编译时)类型,而不是其动态(即运行时)类型


      b
      的静态类型是
      Baap
      ,因此
      b.h
      解析为
      Baap.h
      ,即
      4
      ,因此您的问题是为什么
      b.h
      的计算结果是
      4
      ,而不是
      44
      ,如下所示:

          Baap b = new Beta();  
          System.out.println(b.h + "    " + b.getH());  
                             ^^^ why is this 4?
      
      原因是Java中没有数据多态性。尽管它们共享相同的名称,
      Baap.h
      Beta.h
      是独立的、不相关的字段

      当编译器解析
      b.h
      时,它查看
      b
      的静态(即编译时)类型,而不是其动态(即运行时)类型


      b
      的静态类型是
      Baap
      ,因此
      b.h
      解析为
      Baap.h
      ,即
      4

      字段不遵循重写。讲法语的人写印地语类:)字段不遵循重写。讲法语的人写印地语类:)因此返回h;语句是序列中最后一个要处理的语句。我以为这是继b.getH()之后第二个被处理的;方法调用。非常感谢you@Rahoul:是的,事实上
      getH()
      println()
      中被调用,并且使用
      println()
      会使事情变得混乱。在System.out.println(b.h+“”+b.getH())语句中,我本来希望先打印“b.h”,因为它是println语句的第一个成员,但它没有。你能告诉我为什么吗;语句是序列中最后一个要处理的语句。我以为这是继b.getH()之后第二个被处理的;方法调用。非常感谢you@Rahoul:是的,事实上
      getH()
      println()
      中被调用,并且使用
      println()
      会使事情变得混乱。在System.out.println(b.h+“”+b.getH())语句中,我本来希望先打印“b.h”,因为它是println语句的第一个成员,但它没有。你能告诉我为什么吗?