Java调用子类的前父方法

时间:2014-01-16 09:01:37

标签: java oop inheritance encapsulation

在c ++中,您可以从任何普通的父类轻松调用eny oveloaded方法。 我是如何在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类的相同重载方法?

3 个答案:

答案 0 :(得分:7)

在Java中,如果没有黑客攻击,你就无法做到这一点,因为C不仅仅是A而且只是A.如果你能用C ++做到这一点,那么恕我直言!这表明您的层次结构混乱,C应该只是A而不是B。

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

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

并从C中调用它。


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

答案 1 :(得分:1)

正如其他人已经指出的那样,你不能直接得到它(例如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循环中添加代码来检查并捕获支持它的最后一个超类。

答案 2 :(得分:0)

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