我遇到了Java问题。我有一个可以扩展的方法。问题是,这个方法调用了类的其他方法,并且这些方法也可以扩展。
考虑以下课程:
public class Foo {
protected int xLast;
public updateMe(int x, int y) {
updateX(x);
}
protected updateX(int x) {
this.xLast = x;
}
}
此类由以下类扩展:
public class Bar extends Foo {
protected int xAverage = 0;
protected int xCount = 0;
protected int y;
public updateMe(int x, int y) {
super.updateMe(x, y);
updateX(x);
updateY(x);
}
protected updateX(int x) {
this.xAverage = (this.xAverage * this.xCount) + x;
this.xCount++;
this.xAverage /= xCount;
}
protected updateY(int y) {
this.y = y;
}
}
还有这个班级:
public class Abc extends Foo {
}
当我执行以下操作时:
Foo myBar = new Bar();
myBar.updateMe(1, 2);
未调用Foo.updateX
方法,但调用Bar.updateX
方法两次。有几种解决方案,有些解决方案效果不佳或非常难看:
Bar.updateX
致电super.updateX
。这将导致两个updateX
方法被调用两次。updateX
中的Foo.updateMe
来电,强制扩展类呼叫super.updateX
。这将导致类Abc
拥有它不需要的无用代码,否则Abc类将根本不会调用updateX
。我知道这有点像代码味道,但我认为没有更好的方法可以做到这一点。
基本上我希望做到这样的事情:Foo.updateMe
我想特别致电Foo.updateX
,而不仅仅是多态updateX
。
我相信像C#中的new
方法关键字这样的东西可以解决我的问题,但是Java似乎没有一个或任何其他方法来实现这一点。
修改
最后我选择重命名违规方法。我有一个导致这个问题的方法,这里提出的解决方案,虽然从设计的角度来看声音会使这个特定的代码更难理解和维护。
答案 0 :(得分:3)
我会这样做:
在这种情况下,不必更改Abc,并且一次调用updateX()方法。
答案 1 :(得分:1)
Java,所有实例方法调用都是通过动态绑定调用的。据我所知,没有优雅的方法来实现你想要的东西。
如果你不关心原则和优雅,你可以在Foo检查一个实例的类。
public updateMe(int x, int y) {
if (getClass()==Foo.class)
updateX(x);
}
答案 2 :(得分:1)
updateX()
来自Bar
的原因。
BTW做你想做的事你应该创建静态方法并以这种方式调用它:Foo.updateX()。
答案 3 :(得分:0)
您还可以将updateX()设为私有。然后,实现updateX()的子类是“隐藏”,而不是“覆盖”该方法。
缺点: 由于updateX()在概念上是模板模式的一部分,因此它真的“感觉”应该受到保护。
你不能放
abstract private void updateX();
在超类中强制用户实现它。
updateMe()的所有实现必须始终记得调用updateX()
可能的缺点和可能的优势:
将调用所有私有updateMe()方法。 (对我而言,这是理想的,YMMV)
我最近遇到了这个问题并选择了这个解决方案,虽然我考虑重命名方法和非常接近(getClass()== MyFoo.class)技巧的东西。 IMO都是合理的。