【问题标题】:Java superclass calls subclass methodJava超类调用子类方法
【发布时间】:2015-12-09 14:33:18
【问题描述】:

我有这些课程:

class A {
  public void f() { System.out.println("f() in A"); }
  public void g() { System.out.println("g() in A"); f(); }
}

class B extends A {
  public void f() { System.out.println("f() in B"); }
}

为什么

B b = new B();
A a = b;
a.g();

打印出来

g() in A
f() in B

而不是

g() in A
f() in A

我有什么遗漏吗?

【问题讨论】:

  • 了解多态性和方法覆盖。

标签: java class inheritance


【解决方案1】:

这是因为 Java 默认(并且强制)在类的方法上使用dynamic dispatch。

此功能可确保在调用方法时,选择执行该方法的最专业版本。在您的情况下,由于B extends A,这意味着B 的public void f() 实现比A 的实现更专业。因此,虽然A a 的静态类型为A,但它的动态类型为B,并且选择了该方法。

【讨论】:

    【解决方案2】:

    是的,尽管变量“a”是A类型,但它持有的对象引用是B类型,所以B中的f()就是所谓的。

    【讨论】:

      【解决方案3】:

      https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html

      这称为多态性。它可以让我们做一些事情,比如保存一个 Animal 类型的列表,但是当我们把一只猫放进去,然后执行 animal.performcall() 时,它会打印一个喵。这是我老师多年前给我的例子,反正:)

      【讨论】:

      • 其实这不仅仅是多态,它只是获得多态行为的一种方式,但有多种方式(即使在Java中也是如此)。
      【解决方案4】:

      对象的引用变量类型决定了哪些方法可以访问。

      对象的类决定了存在哪些方法。这些存在但不可访问的方法可以通过强制转换来访问。

      即:((B) a).g(); 将允许您访问 G 的 B 版本。这仅适用于 a 下面是 B。

      【讨论】:

        【解决方案5】:

        现在您了解了多态性和覆盖。

        由于您没有获得预期的输出,我会建议一种通过方法遮蔽或隐藏

        来获得预期输出的方法

        如果您在派生类中重新定义基类非静态和非私有方法,则称为覆盖。

        在这个例子中,A 持有 B 的实例,因此 f() 是从 B 而不是 A 调用的。

        如果重新定义基类静态方法/变量为派生类,则称为hiding或shadowing。

        在上面的示例中,只需添加 static 修改为 g() 方法,您将获得所需的输出。现在g()方法

        class A {
          public static int i=10;
          public static void f() { 
            System.out.println("f() in A:i="+i); 
          }
          public void g() { System.out.println("g() in A"); f(); }
        }
        
        class B extends A {
          public static int i=20;
          public static void f() { 
              System.out.println("f() in B:i"+i); 
          }
        }
        public class Test2 {
            public static void main(String args[]){
                B b = new B();
                A a = b;
                a.g();
            }
        }
        

        输出:

        g() in A
        f() in A:i=10
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-24
          • 2015-04-23
          • 2012-04-18
          • 1970-01-01
          相关资源
          最近更新 更多