简体   繁体   English

从超类中调用超级方法

[英]Calling super method from within super class

As a brain-twister example a professor of mine gave us following exercise, to learn about inheritance. 作为一个扭转脑子的例子,我的一位教授给了我们以下练习,以了解继承。 We had to figure out the output. 我们必须弄清楚输出。

//java
public class A {
    public void f() {
        System.out.println("A -> f()");
        x = x + 4;
        if (x < 15) this.f(); //the f-call
    }
    public int x = 5;
}

public class B extends A {
    @Override
    public void f() {
        System.out.println("B -> f()");
        x = x + 3;
        super.f();
    }
}

public class Main {
    public static void
    main(String[] args) {
        A a = new B();

        System.out.println("a.f()");
        a.f();
        System.out.println(a.x);
    }
}

The output is, as I expected, 正如我所料,输出是

  • af() AF()
  • B -> f() B - > f()
  • A -> f() A - > f()
  • B -> f() B - > f()
  • A -> f() A - > f()
  • 19 19

However, I was now wondering. 但是,我现在想知道。 Is there a way to make the f-call in A call the f method in A, even when I use it from an B-object, similar to the way I call the f from A in B using super.f(). 有没有办法在A中调用f调用 A中的f方法,即使我从B对象使用它,类似于我使用super.f()从B中调用f的方式。 So the output would become (I think): 所以输出会变成(我认为):

  • af() AF()
  • B -> f() B - > f()
  • A -> f() A - > f()
  • A -> f() A - > f()
  • 16 16

Is this possible? 这可能吗? And if so, how? 如果是这样,怎么样?

Note: I'm not sure what the practical application of this would be, I'm just trying to learn something new :P 注意:我不确定这个实际应用是什么,我只是想学习一些新东西:P

The short answer is "no" you cannot do this. 简短的回答是“不”你不能这样做。

The longer answer is that allowing this would break all kinds of guarantees about inheritance. 更长的答案是允许这会破坏对继承的各种保证。 Your B class has essentially said "I now provide the canonical method for public void f() ". 你的B类基本上说“我现在为public void f()提供规范方法”。 Because B is providing said method it is allowed to call back in to the parent to use that (and something that's a very useful thing to do). 因为B提供了所述方法,所以允许回调父母使用它(以及这是非常有用的事情)。

If A was allowed to do the same it would essentially be bypassing the behaviour that B wants to override. 如果A被允许做同样的事情,它基本上会绕过B想要覆盖的行为。

There are a variety of patterns available that give you similar behaviour, eg the Template Pattern 有多种模式可以为您提供类似的行为,例如模板模式

Because polymorphism will apply to all methods of a superclass object, the f that is called will be that of the object's runtime type always -- in this case, B , so B 's f method will always be called. 由于多态性将适用于一个超类对象的所有方法中, f被称为将是永远对象的运行时类型的-在这种情况下, B ,所以Bf方法将总是被调用。 That cannot be changed in Java. 这在Java中是无法改变的。

You may be able to work around this by doing the work of A 's f method in a private method, say, foo , so that when f is called, foo is called repeatedly. 您可以通过在private方法(例如foo执行Af方法来解决此问题,以便在调用f时,重复调用foo In A : A

public void f()
{
   foo();
}

private void foo() {
    System.out.println("A -> f()");  // Lie.
    x = x + 4;
    if (x < 15) this.foo(); //the "f"-call
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM