如何在子类中调用重写的方法?重构的潜在候选对象

busg9geu  于 2021-07-05  发布在  Java
关注(0)|答案(3)|浏览(361)

最初我遇到了一个设计问题,我需要一个超类的五个子类,除了两个子类之外,其他所有子类都将使用相同的泛型方法,其他两个类将需要特殊处理。我想避免把这个方法写五遍;两种特殊情况和三种相同情况。
所以我让每个类继承超类和它的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 ...

那么我该怎么做才能让设计更优雅,更不俗气呢?

t98cgbkg

t98cgbkg1#

我被你的问题弄糊涂了:
当然,我想做的是让每个对象调用它自己版本的dosomething(),但是没有意识到为了做到这一点,obj需要声明为子类方法之一。现在是一团糟。
当然,声明并不重要,dosomething()方法将始终根据类的运行时类型进行调用。
因此,我认为您尝试做的应该很好,例如,这些声明都可以用来传递给foobar方法:

SuperClass sc1 = new SubClassSpecial1();
SubClassSpecial2 sc2 = new SubClassSpecial2();
//etc..
vs3odd8k

vs3odd8k2#

当你有这个:

void fooBar(SuperClass obj) {
    obj.doSomething();
}

然后 objSuperClass . 这意味着编译器将检查 SuperClass 有一个 doSomething() 方法。
在运行时,可以替换 SuperClass ,这就是李斯科夫代换原理。方法 foobar() 不知道,也不应该知道,运行时的类型是什么 obj 是的,只是它来源于 SuperClass 所以呢 doSomething() 可以调用。
至于你的例子:

fooBar( new SubClassSpecial1() );

在本例中,您碰巧知道参数的运行时类型是 SubClassSpecial1 它特别覆盖了 doSomething() . 在所有情况下都会调用正确的方法。
关于重构的一句话。您可能需要考虑重构您的层次结构。
你的基础阶级 SuperClass 应该定义 doSomething() 抽象的。您的三个类需要相同的 doSomething() 应该从具有特定实现的中间基类继承它。您的两个特殊类应该直接从 SuperClass 并有自己的实施方案 doSomething() .

68bkxrlz

68bkxrlz3#

你所描述的应该能正常工作。
dosomething()是否实际调用了超类的实现?如果是的话,您没有正确地重写它。检查是否未更改重写版本中的签名。

相关问题