假设我有一个名为GUIElement的类,由以下代码描述:
public abstract class GUIElement {
public abstract void onScroll();
//Other methods such as getX(), getY(), onClick() etc.
}
所有扩展它的 GUI 元素显然都被迫为 onScroll 编写具体的代码,前提是它们是一个具体的类,但很少有人真正使用这个 onScroll 方法,因为它只在长 GUIText 块这样的东西中很方便。
那么我的问题是,在这种情况下,最佳实践是什么?继续强制所有子类编写代码,即使大部分代码都是空的,或者像这样使其具体化:
public abstract class GUIElement {
public void onScroll() {}
//Other methods such as getX(), getY(), onClick() etc.
}
并让使用它的少数类覆盖它。 或者也许还有其他更好的选择?
如果只有少数类需要实现该方法,那么适配器模式是一个不错的选择。也就是说,你的第二种方法基本上是什么。在父类中有一个空的实现,只有那些需要此功能的子类才能重写它,但它们不会被迫这样做。
例如,看看AWT包中的鼠标适配器。它实现MouseListener
接口,但将所有方法留空。然后,子类可以选择是否重写这些方法。
假设我有一个名为 GUIElement 的类,由以下代码描述:
public abstract class GUIElement { public abstract void onScroll(); //Other methods such as getX(), getY(), onClick() etc. }
所有扩展它的 GUI 元素显然都被迫为 onScroll 编写具体的代码,前提是它们是一个具体的类,但很少有人真正使用这个 onScroll 方法,因为它只在长 GUIText 块这样的东西中很方便。
在抽象类中,方法应该是抽象的,因为这个抽象类中的具体方法使用它们,例如:
public abstract class GUIElement {
public void onScroll(){
// do stuff
SomeObject retunValue = calculateInSomeChiledClass();
// do other stuff
}
potected abstract SomeObject calculateInSomeChiledClass();
}
出于任何其他原因,抽象类不应具有抽象方法。
创建一个空的具体方法是一种方法,但它有一个后果,因为它不会强制新声明的类覆盖它。
如果这个后果对你来说不是缺点,使用这种方式是可以的。
否则,如果要确保子类显式指定如何实现操作,则应将方法保留为抽象方法,并在需要时实现它们,并在不支持该操作的子类中抛出UnsupportedOperationException
或空实现。
这两种解决方案都是可以接受的。
遵循一个或第二个取决于你想要强调的子类的点:简单的API或显式行为来定义。