【问题标题】:Java calling pre-parent method of child classJava调用子类的pre-parent方法
【发布时间】:2014-01-16 09:01:37
【问题描述】:

在 c++ 中,您可以轻松地从任何以前的父类调用 eny 重载方法。 我如何在 Java 中做这样的事情?

例子:

class A {

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

};

class B extends A {

    @Override
    public void f() {  
        super.f();
        System.out.println("B");
    }

};

class C extends B {

    @Override
    public void f() {  
        super.f(); // how to invoke f() method of A class avoiding B class?
        System.out.println("C");
    }

};

所以调用 c.f() 将打印“ABC”。

如何从A类的C类方法调用避免B类的重载方法?

【问题讨论】:

  • 你不能在 Java 中做到这一点。
  • 嗯,比这更可悲。
  • 恕我直言 很遗憾 C++ 会让你以这种方式搞乱层次结构。
  • @CookieMonster 是的。很伤心。
  • 其实很有用。

标签: java oop inheritance encapsulation


【解决方案1】:

在 Java 中,如果没有 hack,您将无法做到这一点,因为 C 是 B 而不仅仅是 A。如果您可以在 C++ 中做到这一点,恕我直言,这是一个坏主意。这表明您的层次结构混乱了,C 应该只是 A 而不是 B。

如果你真的必须这样做,你可以像这样向 B 添加一个方法,这样你就可以绕过 B.f();

protected void superF() {
    super.f();
}

并从 C 中调用它。


可以使用 ASM 生成字节码来执行此操作。字节码允许你调用任何级别的父级,Java 不能。

【讨论】:

  • 我只有 C 类的源代码。
  • @CookieMonster 您可以反编译 B 并“修复”它。你也可以让 C 成为 A 的子类。
  • 我可以从 GrepCode 获得源代码。但是,如果我这样做,那么我将不得不获取那里正在使用的所有其他资源。
  • @CookieMonster 您只需要一个类的源代码,您可以使用已有的已编译类进行编译。如果它没有编译你有错误的版本。
  • @Peter no,“C 类”
【解决方案2】:

正如其他人已经指出的,你不能直接得到它(例如super.super.不起作用)。

这里有一个hack,你可以随意摆弄:

try
{
    Class<?> s = this.getClass();
    while ( !"java.lang.Object".equals(s.getSuperclass().getName())  )
    {
        s = s.getSuperclass();
    }
    Method m = s.getMethod(Thread.currentThread().getStackTrace()[1].getMethodName(), (Class<?>[])null);
    if ( m != null )
    {
        m.invoke(s.newInstance()); // This is the actual call to the 'super' method.
    }
}
catch ( Exception e )
{
    e.printStackTrace();
}

它并不漂亮,但对于简单的类和方法来说它可以工作;)

ps。这个 hack 只支持没有任何参数的方法。如果您需要支持参数,则需要使用getMethods() 方法。此外,如果最终的“超类”不支持该方法,它也将不起作用,但您可以在 while 循环中添加代码来检查并捕获最后一个支持它的超类。

【讨论】:

    【解决方案3】:

    不,这不能在 java 中完成。但是,如果您希望它完成,请在 C 类的重写方法 f() 中创建 A 类的实例,并使用该对象调用 A 类的 f()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-02
      • 2016-05-17
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      相关资源
      最近更新 更多