我希望能够确定基类方法是否已被子类重写,因为在调用它之前需要进行昂贵的设置,并且系统中的大多数子类都不会覆盖它。可以使用反射提供的方法句柄进行测试吗?或者是否有其他方法来测试是否覆盖了类方法?
e.g。
class BaseClass {
void aMethod() { // don nothing }
protected boolean aMethodHasBeenOverridden() {
return( // determine if aMethod has been overridden by a subclass);
}
}
答案 0 :(得分:30)
您可以通过检查方法的声明类来完成反射:
class Base {
public void foo() {}
public void bar() {}
}
class Derived extends Base {
@Override
public void bar() {}
}
...
Method mfoo = Derived.class.getMethod("foo");
boolean ovrFoo = mfoo.getDeclaringClass() != Base.class;
Method mbar = Derived.class.getMethod("bar");
boolean ovrBar = mbar.getDeclaringClass() != Base.class;
System.out.println("Have override for foo: "+ovrFoo);
System.out.println("Have override for bar: "+ovrBar);
打印
Have override for foo: false
Have override for bar: true
答案 1 :(得分:9)
这可以通过调用getClass().getDeclaredMethod("aMethod")
完成,只有当this
的类声明它时才会返回。
以下是您的方法的实现:
/**
* @return true if the instance's class overrode aMethod
*/
protected boolean aMethodHasBeenOverridden() {
try {
return getClass() != A.class && getClass().getDeclaredMethod("aMethod") != null;
} catch (NoSuchMethodException | SecurityException e) {
return false;
}
}
答案 2 :(得分:2)
我采取的方法是,如果子类需要通过重写在抽象中间类中调用它的方法来使该方法存在。这是什么样子:
public abstract class MovingThing {
public void move() {
// walk a few feet
}
}
现在你的一些移动物品传送,但这需要为助焊剂电容器和其他昂贵的东西充电,所以将它分开:
public abstract class TeleportingThing extends MovingThing {
@Override
public void move() {
fluxCapacitor.charge();
stardate.calculate();
doTeleport();
}
protected abstract void doTeleport();
}
您需要昂贵设置的课程来自包含它的第二课程,而那些不能从第一课程派生的课程。这种模式是一种Decorator,例如,在Servlet API中使用,其中大多数servlet覆盖类似doGet()
的内容,并将解析保留为service()
。