我正在研究一些框架,我得到了一个抽象类,应该实现它.
现在我得到了一些用户应该能够配置的其他东西,但它是可选的.
而不是抽象方法:
public abstract class AbstractModule { public void doSomething() { if (logMessage() != null) System.out.println(logMessage()); doStuff(); } protected abstract String logMessage(); // I'm optional protected abstract void doStuff(); }
我想只是检查接口实现:
public interface Log { String logMessage(); } public abstract class AbstractModule { public void doSomething() { if (this instanceof Log) { if (((Log) this).logMessage() != null) System.out.println(((Log) this).logMessage()); } doStuff(); } protected abstract void doStuff(); }
因此,如果有人使用接口Log实现AbstractModule,它也会显示消息.我看到的实现者的好处是:她不需要关心实现logMessage(),就像在第一个例子中那样.这是一种有效的方法还是应该以不同的方式完成?
提前致谢!
最好的祝福
我会将Logger作为模块的一个组件,并在抽象类中定义一个默认的无操作记录器.这样你摆脱了instanceof
仍然保持灵活性.
interface Log { void logMessage(); } public abstract class AbstractModule { protected Log log; public AbstractModule(){ this.log = () -> {}; } public AbstractModule(Log log){ this.log = log; } public void doSomething() { log.logMessage(); doStuff(); } protected abstract void doStuff(); }
这是一个示例类扩展AbstractModule
:
public class Module extends AbstractModule{ public Module(){ super(() -> System.out.println("message")); } @Override protected void doStuff() { // do stuff } }
如果要公开记录器,可以在抽象类中为记录器定义getter方法:
public Log getLogger(){ return log; }
由于此问题已被标记为java-8
,另一种解决方案是使用interface
和default
方法:
public interface Module { public default void doSomething() { if (logMessage() != null) System.out.println(logMessage()); doStuff(); } public default String logMessage() { return null; } // I'm optional public void doStuff(); }
用法:
class NoLogModule implements Module { @Override public void doStuff() { } } class LogModule implements Module { @Override public void doStuff() { } @Override public String logMessage() { return "Message "; } }
使用此方法而不是Abstract类的一个优点是您的类现在可以自由地从另一个类扩展.这种方法的一个缺点是你无法阻止某人覆盖该doSomething
方法(基于你的代码,它看起来不像你关心这个)