这可能是一个难题。我认为 Cruncher 的解决方案,添加
到 X 并在, ,doStuff
中覆盖它是最简单和最好的解决方案,如果合适的话。但是,由于单一责任原则,它并不总是合适的。(我认为这是正确的术语。如果我弄错了一些术语,我深表歉意,我并不完全了解所有术语。)A
B
C
这个想法是,doStuff
如果X
它与X
. 如果X
并且Y
是同一个“团队”的一部分,即它们都被设置为服务于一个特定应用程序的目的,那么它可能没问题。
但是假设您有一个具有子类、、、等的抽象Shape
类
。将有一些属于该类的方法,这些方法对使用该类的任何应用程序都很有用。但是现在假设您正在编写一个使用其中一些形状的游戏,并且您想要一个多态操作来确定当形状被飞猴吃掉时会发生什么。你不会想在
你的类中添加一个抽象方法,即使这个类是你自己创建的,而不是在别人的库中,因为这对于一个通常可以用于除此之外的其他目的的类来说太具体了游戏。Circle
Square
Undecagon
RandomBlob
Shape
Shape
computeEatenByFlyingMonkey
Shape
我可以想到几种方法来解决这个问题。
如果不适合(或不可能)添加doStuff
到X
,但如果A
、B
和C
与您的应用程序更紧密地连接,以便添加doStuff
到它们是合适的,您可以添加另一个类:
public abstract class XWithStuff extends X {
// repeat any constructors in X, making them all be just
// calls to super(...)
public abstract void doStuff (Boolean flag);
}
public class A extends XWithStuff {
@Override
public void doStuff (Boolean flag) { ... }
}
以此类推。(XWithStuff
只是一个示例名称;在现实生活中,包含“X”和一些对应用程序或目的的引用的名称可能会更好。)(PS 我不知道你为什么使用Boolean
而不是,boolean
但我如果有充分的理由,请保持这种状态。)
doStuff
如果添加到A
、
B
和也不合适或不可能C
,这里有一个可能的解决方案:
public interface StuffInterface {
public void doStuff (Boolean flag);
}
public class AWithStuff extends A implements StuffInterface {
@Override
public void doStuff (Boolean flag) { ... }
}
然后在您的程序中创建类对象AWithStuff
而不是A
等。doStuff
调用X
:
void doStuff (X x, Boolean flag) {
if (x instanceof StuffInterface) {
((StuffInterface) x).doStuff (flag);
} else {
throw new IllegalArgumentException ();
}
}
如果这不是一个选项并且您必须直接处理A
,B
等,并且您无法添加doStuff
到这些类中,那么任何解决方案都会有点笨拙。如果您不想使用if
- then
- else
,您可以查看访问者模式,或者您可以想象创建一个HashMap<Class<?>,Interf>
将 , 等映射A.class
到B.class
调用正确doStuff
. 但我还没有弄清楚细节。(实际上,“访问者模式”可能不合适,除非你有某种由 X 类型的对象组成的复杂结构。)