这样做有关键字或设计模式吗?
public abstract class Root
{
public abstract void foo();
}
public abstract class SubClass extends Root
{
public void foo()
{
// Do something
//---------------- Update -------------------//
// This method contains important code
// that is needed when I'm using a instance
// of SubClass and it is no instance of any
// other class extending SubClass
}
}
public class SubberClass extends SubClass
{
// Here is it not necessary to override foo()
// So is there a way to make this necessary?
// A way to obligate the developer make again the override
}
由于
答案 0 :(得分:9)
如果你这样做,那么你可能会滥用继承;与流行的神话相反,继承不是用于制作自定义钩子/处理程序,而是用于启用替代实现。
如果您希望用户提供某种函数/钩子/回调,那么您应该定义一个接口,该接口仅提供您需要用户定义的那些方法。然后,您应该要求用户将该接口的实例传递给对象的构造函数,或者将其传递给需要它的函数。
聚合,委托和组合通常比继承更好,更安全的设计模式;强迫其他用户从你的类继承,这是非常冒险的,因为它为用户提供了很多机会来违反你的类的合同或使你的基类的不变量无效。
答案 1 :(得分:3)
如果每个继承SubClass
的类都必须覆盖foo()
,那么为什么要在SubClass
中提供实现呢?您只需从SubClass
中删除方法定义,然后将强制所有子类提供实现。
答案 2 :(得分:1)
如果你真的想,你可以将foo重新声明为抽象。
public abstract class SubberClass extends SubClass
{
public abstract void foo();
}
答案 3 :(得分:0)
而不是覆盖foo()
中的SubClass
,而是创建一个新方法fooImpl()
并留下foo()
摘要。这样,所有类都必须实现foo()
,但如果已经足够的话,您可以通过调用fooImpl()
来实现它。
答案 4 :(得分:0)
是的,没有必要覆盖foo()
中的SubberClass
。
答案 5 :(得分:0)
你无法双管齐下。您不能提供具有默认实现的方法,并且要求子类覆盖它。您可以使用声明的方法定义接口(IFoo),然后提供实现接口的抽象类,而不是在Root中将该方法声明为抽象。这仍然需要一个具体的子类,但不需要方法覆盖。
大多数情况下,当您看到这种类型的模式时,接口用于定义一组方法,而抽象基类为接口中的某些但不是所有方法提供一些默认实现。这要求具体子类为其余方法提供代码,并使用选项覆盖默认行为。
在任何情况下,您都无法为单个方法提供默认行为,并且需要子类覆盖相同的方法。