在Java中继承属性。新实例?

时间:2015-07-27 09:49:30

标签: java inheritance logging encapsulation

关于java中继承的一个非常简单的问题:

我的抽象超类(仅限相关内容):

public abstract class Writer {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    public Logger getLog() {
        return log;
    }
}

我的一个子类:

public class ConcreteWriter extends Writer {

    public void write1(){
      getLog().error("msg1");
      getLog().info("msg2");
      getLog().warn("msg3");
      getLog().error("msg4");
    }
}

你可以看到' getLog()'每当我需要写一条消息时,我都会重复这一消息,而且我认为这不是优雅的,而且它可能效率也不高。

我不想打破OO编程的封装原则,所以我拒绝使用访问修饰符' protected'在超类中(直接使用" log"变量)。

你怎么看?在子类中创建我的日志的新实例会更好吗?或类似的东西:

public class ConcreteWriter extends Writer {

    private final Logger log = getLog();

    public void write1(){
      log.error("msg1");
      log.info("msg2");
      log.warn("msg3");
      log.error("msg4");
    }
}

1 个答案:

答案 0 :(得分:4)

两个单独的字段总是具有相同的值对我来说似乎是一个非常糟糕的主意。你在逻辑上没有两个不同的状态,那么为什么要有两个不同的字段呢?相反,只需在write1中使用局部变量即可避免多个getLog()调用:

public void write1(){
  Logger log = getLog();
  log.error("msg1");
  log.info("msg2");
  log.warn("msg3");
  log.error("msg4");
}

对于特别的记录,我倾向于每个类都有一个私有的静态final字段,而不是在其他地方公开它。您不太可能每个实例需要一个不同的记录器,在我看来,记录应该被视为实现细节而不是API的一部分。

所以我有:

public class Writer {
    private static final Logger LOG = ...;

    // Use LOG when I need to
}

public class ExtendedWriter extends Writer {
    private static final Logger LOG = ...;

    // Use LOG when I need to
}