【问题标题】:java override method invocationjava覆盖方法调用
【发布时间】:2012-02-15 09:08:19
【问题描述】:

我有一个超类:

public class SuperClass {

    public void dosomething() {
        firstMethod();
        secondMethod();
    }

    public void firstMethod() {
        System.out.println("Super first method");
    }

    public void secondMethod() {
        System.out.println("Super second method");
    }
}

一个子类:

public class SubClass extends SuperClass {

    public void dosomething() {
        super.dosomething();
    }

    public void firstMethod() {
        System.out.println("Sub first method");
    }

    public void secondMethod() {
        System.out.println("Sub second method");
    }
}

一个测试类:

public static void main(String[] args) {
      SubClass sub = new SubClass();
      sub.dosomething();
      SuperClass sup = new SuperClass();
      sup.dosomething()
}

当我运行测试方法时,我得到了这个:

Sub first method
Sub second method

你能告诉我这是怎么发生的吗?在子类dosomething方法中,我调用了super.dosomething(),我认为super方法会被调用,但是子类中的override方法被调用了。

如果我这样做:
SuperClass superClass = new SuperClass();
superClass.dosomething();


结果是:
超级第一法
超秒法

区别在于方法调用的地方。我想肯定有什么我不知道的):

哎呀!第一个例子中的超级引用指向了子类...

像这样:

SuperClass sub = new SubClass();
sub.firstMethod();
sub.secondMethod();

【问题讨论】:

    标签: java methods overriding


    【解决方案1】:

    在java中,方法binding总是dynamic[忽略这里的静态和私有方法]。因此,当您覆盖firstMethod()secondMethod() 时,任何时候SubClass 类型的对象都会尝试调用其中一个- 将调用被覆盖的方法- 即使它[调用] 来自父方法。

    因此,正如预期的那样 - 当您调用 super.doSomething() 时,它会调用 firstMethod()secondMethod(),并且正在调用覆盖的方法。

    【讨论】:

    • "(忽略静态和私有方法)"
    • @JoachimSauer:在答案中添加了私有异常。谢谢。
    【解决方案2】:

    调用方法的对象是 SubClass 类型,而不是 SuperClass。即使您调用仅在 SuperClass 中定义的方法,您的执行上下文仍然是 SubClass。所以任何被调用的被覆盖的方法实际上都会执行被覆盖的方法。

    要摆脱这一点的是,通过将 firstMethod 和 secondMethod 声明为 public,SuperClass 实际上允许子类覆盖它们的行为。如果这不合适,则方法应该是私有的或最终的。

    【讨论】:

    • 我觉得这个功能很好用,只是不知道具体是怎么用的:(
    • @Felix:你不明白什么?重要的是对象的运行时类型,而不是定义变量的类型。
    【解决方案3】:

    确实调用了超级doSomething。调用 firstMethod 和 secondMethod,它们是虚拟方法(Java 中的任何方法默认都是虚拟的,这意味着它可以被覆盖)。所以他们的覆盖版本被调用。

    如果将它们标记为 final,则可以防止它们被覆盖。

    【讨论】:

      【解决方案4】:

      Super.dosomething() 实际上调用了Super 类中的dosomething() 方法。但是在这个方法中,你调用了 2 函数,它们是 firstMethodsecondMethod。这些方法在Sub 类中被覆盖,它们是从Sub 类中调用的。

      正如 Petar Ivanov 建议的那样:

      如果将它们标记为 final,则可以防止它们被覆盖

      【讨论】:

      • 我们如何调用 Super 类的方法...this.firstMethod() 会在基类的 doSomeThing() 中代替 firstMethod() 工作吗???....
      • @aProgrammer 还是一样。
      • @Felix 如果它们被 NOT 标记为最终结果,它仍然是一样的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-27
      • 1970-01-01
      • 2011-12-13
      • 2022-01-23
      • 1970-01-01
      • 2018-01-30
      • 2020-01-30
      相关资源
      最近更新 更多