Java:当其他类已经扩展了基类时,如何扩展基类?

8
我想要扩展apache commons email中的基类,该基类为Email。我只是想在.send()方法中添加一些节流功能。
另外还有三个类继承自Email:HtmlEmail、SimpleEmail和MultiPartEmail。
这三个派生类没有工厂方法可以创建。
有没有最好的方法可以从基类Email中扩展出这个方法?我所能想到的就是扩展这三个派生类,在每个类中重写.send()方法,并让它们调用一个共同的静态方法来实现.send()的节流功能。
1个回答

19
看起来你可以使用装饰器模式,例如编写ThrottledEmail。它只是装饰另一个Email实例(它可以是任何Email子类),并且可以@Override send方法以强制执行一些限流措施。所有其他方法都只是委托给基础的Email实例。
这类似于例如java.io.BufferedReader的工作方式。它可以装饰任何Reader以提供缓冲功能。其他示例包括java.util.Collections,它提供了实用方法,例如Collection<T> synchronizedCollection(Collection<T>),它包装了任何Collection<T>并将其装饰为同步特性。
除非基类明确记录以便子类@Override某些方法,否则通常应优先选择组合(has-a)而不是继承(is-a)关系。

另请参见

  • Effective Java 2nd Edition,第16条:优先使用组合而非继承
  • Effective Java 2nd Edition,第17条:为继承设计和记录文档,否则就禁止它

相关问题


这很棒,我已经阅读了许多关于这种模式的教程。但是我还没有完全掌握它:如果我需要一个HtmlEmail(它扩展了Email),并且我只需要向Email.send()添加功能,那么我是否还需要一个HtmlEmail的ConcreteDecorator(以及所有其他Email子类的ConcreteDecorator - SimpleEmail和MultiPartEmail,并实现将所有相应方法转发到具体对象)? - David Parks
@David:你可以为每个装饰创建具体的装饰器。因此,你可以有一个“限流电子邮件”,它会限制任何“电子邮件”的发送,然后你可以在其他方面的“电子邮件”上进行进一步的装饰(例如,“自动签名电子邮件”或其他),并将它们叠加在一起。这应该不会真正影响你是在装饰“HtmlEmail”还是“SimpleEmail”。 - polygenelubricants

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接