我无法找到一个很好的总结来描述我的问题(建议欢迎)
我有两节课:
测试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是抽象的。所以我无法创建它的对象。
答案 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方法状态。继承并不像那样工作。