在超类中调用超类方法

时间:2013-01-16 12:02:25

标签: java inheritance override subclass superclass

我无法找到一个很好的总结来描述我的问题(建议欢迎)

我有两节课:

测试1

import java.lang.reflect.Method;

abstract class Test1 {

    boolean condition = true;

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

    public void g() {
        System.out.println("Test1 : g");
        f();
        if (condition) {
            f(); // call Test1.f() here. HOW?

            // Following didn't work
            try {
                Method m = Test1.class.getDeclaredMethod("f");
                m.invoke(this);
            } catch (Exception e) {
                System.err.println(e);
            }
        }
    }
}

的Test2

class Test2 extends Test1 {

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

    public static void main(String[] args) {
        Test2 t2 = new Test2();
        t2.g();
    }

}

输出结果为:

Test1 : g
Test2 : f
Test2 : f
Test2 : f

问题在于,由于condition中的Test1字段提供了一些特殊条件,我想在Test1中呼叫f()的{​​{1}}即使我正在使用g()的对象进行调用。

我尝试过反射但它也不起作用。有什么建议吗?

编辑1: 我没有具体提到它,但如果你仔细看,Test1是抽象的。所以我无法创建它的对象。

6 个答案:

答案 0 :(得分:3)

您应该认真考虑您要构建的逻辑。您试图覆盖子类中的方法f的原因确定了它背后的原因。

或者,您可以将boolean值作为方法f的返回值,并在子方法中使用boolean r = super.f(); if(r){//execute child logic.}这可以解决您的问题。

答案 1 :(得分:2)

我的理解。

您的问题:
如果g()f()类中调用方法Test1那么为什么它运行f()的子(Test2)类。

答案:来自JLS-8.4.8.1

子类Test2声明了一个方法f(),它覆盖了Test1的方法f()。它继承了Test1类中的方法g()

关于覆盖此示例的关键点是,在类Test1中声明的方法g()调用当前对象f()定义的this方法,该方法不是必须是在Test1类中声明的f()方法。

因此,当使用Test2对象t2在main中调用g()时,在f()方法的主体中调用g()f()的调用对象t2。这允许Test1的子类改变f()方法的行为而不重新定义它。

<强>震荡:

因此,如果某个类覆盖其父级的某些方法,那么契约表示,旨在扩展的Test1应该清楚地指出该类与其子类之间的契约,并且应该清楚地表明子类可以覆盖{ {1}}这种方法。

答案 2 :(得分:1)

在Test1中添加方法f2:

private void f2() {
    System.out.println("Test1 : f");
}
public void f() {
    this.f2()
}

这样你可以在条件为真时调用f2()。

答案 3 :(得分:0)

如果方法名称相同,则无法执行此操作。
其他方法可以使用super.f()直接在子类中调用超类方法。

答案 4 :(得分:0)

UPD:特别针对那个不太注意的人,我给的是 说明。

在下面的代码中,我使用方括号{ }创建新的匿名类。这允许我创建子类Test1的新实例。


而不是使用reflection,你可以做一些有趣的事情:

public void g() {
    System.out.println("Test1 : g");
    f();
    if (condition) {
         new Test1(){}.f();
    }
}

唯一的缺点是调用这种方式的f()方法是调用绝对另一个对象的方法。

答案 5 :(得分:0)

继承只允许您继承行为super.f(),覆盖@Override或两者

@Override
public void f(){
    super.f(); 
    //do something  
}

您无法覆盖方法,然后在覆盖之前尝试调用parents方法状态。继承并不像那样工作。