2014-01-16 53 views
2

在C++中,您可以轻松地从任何以前的父类中调用enveloper方法。 我如何在Java中做这样的事情?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”。

如何从一类避免B级的相同重载的方法的C级方法调用?

+3

你不能用Java来做到这一点。 –

+0

好吧,它比很难过。 –

+1

恕我直言,C++会让你以这种方式混淆层次结构,这是非常令人伤心的。 –

回答

1

正如其他人已经指出的那样,你不能让它直接(例如super.super.不工作)。

这里是一个破解可以更动:

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。这个黑客只支持没有任何参数的方法。如果您需要支持参数,则需要使用getMethods()方法。另外,如果最终的“超类”不支持该方法,它也不起作用,但是您可以在while循环中添加代码来检查并捕获支持它的最后一个超类。

7

在Java中,你不能没有一个黑客做到这一点,因为C是B不只是一个答:如果您可以在C++做到这一点,这是一个坏主意恕我直言。这表明你的层次结构是搞砸了和C应该只有一个A而不是B.

如果你真的要做到这一点,你可以添加一个方法到B这样的,所以你可以绕过B.f();

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

和从C.


有可能使用ASM做到这一点,以产生字节代码调用此。字节码允许你调用任何级别的父级,而不是Java。

+0

我只有C类的源代码。 –

+0

@CookieMonster你可以反编译B并“修复”它。你也可以使C成为A的一个子类。 –

+0

那么我可以从GrepCode获得源代码。但是,如果我会这样做,那么我将不得不获得所有其他在那里使用的来源。 –

0

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