我有一个基础课,Base
。它有两个子类,Sub1
和Sub2
。每个子类都有一些其他方法。例如,Sub1
has Sandwich makeASandwich(Ingredients... ingredients)
和Sub2
has boolean contactAliens(Frequency onFrequency)
。
由于这些方法采用不同的参数并且做的事情完全不同,因此它们是完全不兼容的,我不能仅使用多态来解决此问题。
Base
提供了大多数功能,并且我有大量的Base
对象集合。但是,所有Base
对象都是a Sub1
或a Sub2
,有时我需要知道它们是什么。
执行以下操作似乎是个坏主意:
for (Base base : bases) {
if (base instanceof Sub1) {
((Sub1) base).makeASandwich(getRandomIngredients());
// ... etc.
} else { // must be Sub2
((Sub2) base).contactAliens(getFrequency());
// ... etc.
}
}
因此,我想出了一个避免这种情况的策略。 Base
现在有以下方法:
boolean isSub1();
Sub1 asSub1();
Sub2 asSub2();
当然,将Sub1
这些方法实现为
boolean isSub1() { return true; }
Sub1 asSub1(); { return this; }
Sub2 asSub2(); { throw new IllegalStateException(); }
并Sub2
以相反的方式实现它们。
不幸的是,现在Sub1
,Sub2
这些方法已在自己的API中使用。因此,我可以在上执行此操作Sub1
。
/** no need to use this if object is known to be Sub1 */
@Deprecated
boolean isSub1() { return true; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub1 asSub1(); { return this; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub2 asSub2(); { throw new IllegalStateException(); }
这样,如果已知对象仅为a Base
,则不建议使用这些方法,并且可以使用这些方法将自身“转换”为其他类型,以便可以在其上调用子类的方法。在某种程度上,这对我来说似乎很优雅,但是,另一方面,我有点在滥用“不推荐使用的注释”,以从类中“删除”方法。
由于Sub1
实例实际上是一个 Base,因此使用继承而不是封装确实有意义。我做得好吗?有解决这个问题的更好方法吗?
instanceof
,它需要大量的输入,容易出错,并且很难添加更多的子类。
Sub1
并且Sub2
不能互换使用,那么为什么要这样对待它们呢?为什么不分别跟踪您的“三明治制造者”和“外来接触者”?