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

oli*_*ren 5 java polymorphism refactoring overriding subclass

最初我有一个设计问题,我需要五个超类的子类,其中除了两个之外的所有子类都使用相同的通用方法,而另外两个类需要特殊处理.我想避免写五次这个方法; 两个特殊情况和三个相同的情况.

所以我让每个类继承SuperClass及其doSomething()方法,并使用自己的doSomeThing方法覆盖SubClassSpecial1和SubClassSpecial2.

这一切都很好,直到我写了一个类似的方法

void fooBar(SuperClass obj) {
    obj.doSomething()
}
Run Code Online (Sandbox Code Playgroud)

它可以被称为 fooBar( new SubClassSpecial1() );

问题是obj变量的运行时类现在是其超类的运行时类,因此它将调用超类中定义的方法.当然,我可以在超类中创建一个抽象的doSometing()方法,并使每个子类实现自己的版本,但这会重复三个类中的代码.我想避免这样做......

如果我有很多分支,我会失去任何增益多态性

if(obj.getClass().getName() == "SubClassSpecial1" )  ((SubClassSpecial1) obj).doSomething()K;
else if ...
Run Code Online (Sandbox Code Playgroud)

那么我该怎么做才能让设计更优雅,更不讨人喜欢呢?

Nic*_*kDK 5

我对你的这部分问题感到有些困惑:

当然,我想要做的是让每个对象调用它自己的doSomething()版本,但是没有意识到为了做到这一点,需要将obj声明为子类方法之一.而现在这是一团糟.

当然声明无关紧要,doSomething()方法将始终根据类的运行时类型进行调用.

所以我认为你要做的事应该工作得很好,例如这些声明都可以用来传递给foobar方法:

SuperClass sc1 = new SubClassSpecial1();
SubClassSpecial2 sc2 = new SubClassSpecial2();
//etc..
Run Code Online (Sandbox Code Playgroud)

  • 不,你假设有点偏离,使用'new'关键字实例化新对象时使用的类确定对象的运行时类型.因此在我的示例中,SuperClass sc1变量包含对运行时类型为SubClassSpecial1的对象的引用.我现在这可能有点混乱,我希望你明白:-) (2认同)

Ter*_*cox 2

你所描述的应该可以正常工作。

obj.doSomething() 实际上调用超类的实现吗?如果是,则说明您没有正确覆盖它。检查您是否未更改覆盖版本中的签名。

  • 你的假设是错误的。您不需要将 obj 转换为 SubClassSpecial1 来获取 SubClassSpecial1 doSomething() 方法,它会自动发生。这就是多态性。尝试一些测试。 (2认同)