最初我遇到了一个设计问题,我需要一个超类的五个子类,除了两个子类之外,其他所有子类都将使用相同的泛型方法,其他两个类将需要特殊处理。我想避免把这个方法写五遍;两种特殊情况和三种相同情况。
所以我让每个类继承超类和它的dosomething()方法,让subclassspecial1和subclassspecial2用它们自己的dosomething方法重写。
在我写了一个类似
void fooBar(SuperClass obj) {
obj.doSomething()
}
它可以被称为 fooBar( new SubClassSpecial1() );
问题是 obj
变量现在是它的超类的变量,因此它将调用在超类中定义的方法。当然,我可以在超类中创建一个抽象的dosometing()方法,并使每个子类实现自己的版本,但这会在三个类中复制代码。我想避免这样做。。。
如果我有很多分支,我会失去任何收益
if(obj.getClass().getName() == "SubClassSpecial1" ) ((SubClassSpecial1) obj).doSomething()K;
else if ...
那么我该怎么做才能让设计更优雅,更不俗气呢?
3条答案
按热度按时间t98cgbkg1#
我被你的问题弄糊涂了:
当然,我想做的是让每个对象调用它自己版本的dosomething(),但是没有意识到为了做到这一点,obj需要声明为子类方法之一。现在是一团糟。
当然,声明并不重要,dosomething()方法将始终根据类的运行时类型进行调用。
因此,我认为您尝试做的应该很好,例如,这些声明都可以用来传递给foobar方法:
vs3odd8k2#
当你有这个:
然后
obj
是SuperClass
. 这意味着编译器将检查SuperClass
有一个doSomething()
方法。在运行时,可以替换
SuperClass
,这就是李斯科夫代换原理。方法foobar()
不知道,也不应该知道,运行时的类型是什么obj
是的,只是它来源于SuperClass
所以呢doSomething()
可以调用。至于你的例子:
在本例中,您碰巧知道参数的运行时类型是
SubClassSpecial1
它特别覆盖了doSomething()
. 在所有情况下都会调用正确的方法。关于重构的一句话。您可能需要考虑重构您的层次结构。
你的基础阶级
SuperClass
应该定义doSomething()
抽象的。您的三个类需要相同的doSomething()
应该从具有特定实现的中间基类继承它。您的两个特殊类应该直接从SuperClass
并有自己的实施方案doSomething()
.68bkxrlz3#
你所描述的应该能正常工作。
dosomething()是否实际调用了超类的实现?如果是的话,您没有正确地重写它。检查是否未更改重写版本中的签名。