3

我找不到一个好的总结来描述我的问题(欢迎提出建议)

我有以下两个课程:

测试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);
            }
        }
    }
}

测试2

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我使用.Test1f()g()Test2

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

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

4

6 回答 6

3

You should seriously consider the logic you are trying to build. The reason you tried to override the method f in child class has sure a reason behind it.

Alternatively, you can have boolean value as return from method f and in child method use boolean r = super.f(); if(r){//execute child logic.} This should solve your problem.

于 2013-01-16T12:08:56.403 回答
2

我的理解。

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

答案: 来自JLS-8.4.8.1

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

本例中关于覆盖的关键点在于,g()Test1类中声明的方法调用f()了当前对象定义的方法,而当前对象this不一定是f()Test1类中声明的方法。

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

脑震荡:

因此,如果某个类覆盖了其父类的某个方法,则契约说,Test1 旨在扩展,应该清楚地表明类与其子类之间的契约是什么,并且应该清楚地表明子类可以f()以这种方式覆盖该方法.

于 2013-01-25T11:33:06.933 回答
1

Add a method f2 in Test1:

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

This way you can call f2() when the condition is true.

于 2013-01-16T12:07:15.017 回答
0

如果方法名称相同,则不能这样做。
其他方式是可以通过使用 super.f() 直接在子类中调用超类方法。

于 2013-01-16T12:11:20.853 回答
0

继承只允许您继承行为super.f()、覆盖它@Override或两者兼而有之

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

您不能覆盖一个方法,然后在它被覆盖之前尝试调用父方法状态。继承不是这样工作的。

于 2013-01-16T12:44:52.713 回答
0

UPD:专门针对那个不太专心的人,我正在做解释。

在下面的代码中,我正在使用括号创建新的匿名{ }类。这使我可以创建 subclassed 的新实例Test1


而不是使用reflection你可以做这样有趣的事情:

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

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

于 2013-01-16T12:23:00.147 回答