我的两个选项:
1)将该方法设为抽象的,并为每个除了我关注的子类以外的子类重复相同的代码。
2)在关注的子类中覆盖非抽象方法,在那里我想要修改逻辑。
Java中覆盖非抽象方法好吗?概念上,覆盖非抽象方法与抽象方法有什么区别?
在一定程度上,这是一个风格问题。
这是一个普遍的做法 - 但也有人告诉你,任何方法都不应该有超过一个实现。这些人声称,在继承层次结构中存在多个实现会导致很难调试的代码 - 因为您必须非常小心地确定实际调用了哪个版本的这种方法。
当其他方法大量使用此类方法时,您可能会很容易失去大局 - 突然间,因为一些子类中的重写而变得复杂,很难预测某些代码正在执行什么操作。
理解的关键:在 X 类中,某个方法 foo()
的“单一” @Override 是可以的、普遍的、良好的做法。但是在 X 的子类中再次覆盖相同的 foo()
- 这可能很快引起各种问题。
换句话说:仔细处理重新实现非抽象方法。如果它使您的代码难以理解,请寻找其他解决方案。例如:基类具有一个固定(final)方法来执行操作 - 该方法调用其他 抽象 方法来完成其工作。示例:
public abstract class Base {
public final int doSomething() {
String tmp = foo();
int result = bar(tmp);
return result * result;
}
public abstract String foo();
public abstract int bar(String str);
正如所写:在这里,您可以看到由于doSomething()
是final,因此实现是“固定的”,但必须在每个子类中覆盖所需的“配料”。
在Java中覆盖非抽象方法是一种好的实践吗?
是的。(但请确保您没有违反Liskov替换原则
(参考现有的SO帖子),该原则告诉子类不应该破坏父类类型定义。例如,从Animal
类重写的walk()
方法应该执行(具有)行走的行为,它不应该执行飞行或其他行为。)
我还建议您阅读SOLID原则以了解设计原则。
覆盖非抽象方法和抽象方法在概念上有什么区别。
据我所知,没有区别。但是,为了明确起见,抽象方法不包含任何实现,您必须进行覆盖,而非抽象方法可以被覆盖。
在相关的子类中覆盖非抽象方法,以便我想要更改逻辑 - 是的
例如: 如果您考虑Object类中的toString()和hashCode()方法,这两种方法都是非抽象方法,但通常建议在子类中覆盖这些方法。
因为如果我想执行自己的逻辑而不是超类的逻辑,需要覆盖并使用它,在这种情况下建议进行覆盖。