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

继承Java中的属性。新实例?,java,inheritance,logging,encapsulation,Java,Inheritance,Logging,Encapsulation,关于java中的继承,有一个非常简单的问题: 我的抽象超类(仅相关内容): 我的一个子类: public class ConcreteWriter extends Writer { public void write1(){ getLog().error("msg1"); getLog().info("msg2"); getLog().warn("msg3"); getLog().error("msg4"); } } 正如您所看

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

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

我的一个子类:

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");
    }
}

拥有两个始终具有相同值的独立字段对我来说似乎是一个非常糟糕的主意。逻辑上你没有两个不同的状态,为什么有两个独立的字段呢?相反,只需在
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
}

拥有两个始终具有相同值的独立字段对我来说似乎是一个非常糟糕的主意。逻辑上你没有两个不同的状态,为什么有两个独立的字段呢?相反,只需在
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
}

就我个人而言,我甚至不认为添加局部变量有多大用处。代码并没有变得更加清晰(但这显然只是一种观点)。对我来说,这听起来有点像过早的优化,因为调用getter应该不是很关键,特别是在我们讨论Log4j日志消息时;-)让它成为一个受保护的最终变量可能是可以的,但我个人也更喜欢getter方法,因为如果需要的话,您可以更容易地重写getter(老实说,我不认为有太多机会这样做)。对于其他对象,这可能更有意义。@FlorianSchaetz:我同意这对优化并不重要,但我可能会避免重复方法调用,只是为了可读性。我个人觉得这段代码比问题中的第一个示例更干净。谢谢你们。所以,您认为这个选项比在每个子类中使用一个log变量,而不是从超类继承它更好吗?关于这个话题,哪一个是最好的做法?@John Skeet:当然,我不能提供任何真正的反对理由,因为我认为这可能(也是)个人品味的问题。当然,我可能错了。我们如何判断某件事物是否比其他事物更客观?@Emilio:据我所知,这不是你提出的选项。基本上,对于超类来说,
log
变量重要吗?您实际上是在谈论日志记录,还是这只是一个例子?(对于日志记录,我很想让每个类去做它想做的事情,但那样我就没有
getLog()
方法了……)就个人而言,我甚至不认为添加局部变量有多大用处。代码并没有变得更加清晰(但这显然只是一种观点)。对我来说,这听起来有点像过早的优化,因为调用getter应该不是很关键,特别是在我们讨论Log4j日志消息时;-)让它成为一个受保护的最终变量可能是可以的,但我个人也更喜欢getter方法,因为如果需要的话,您可以更容易地重写getter(老实说,我不认为有太多机会这样做)。对于其他对象,这可能更有意义。@FlorianSchaetz:我同意这对优化并不重要,但我可能会避免重复方法调用,只是为了可读性。我个人觉得这段代码比问题中的第一个示例更干净。谢谢你们。所以,您认为这个选项比在每个子类中使用一个log变量,而不是从超类继承它更好吗?关于这个话题,哪一个是最好的做法?@John Skeet:当然,我不能提供任何真正的反对理由,因为我认为这可能(也是)个人品味的问题。当然,我可能错了。我们如何判断某件事物是否比其他事物更客观?@Emilio:据我所知,这不是你提出的选项。基本上,对于超类来说,
log
变量重要吗?您实际上是在谈论日志记录,还是这只是一个例子?(对于日志记录,我很想让每个类去做它想做的事情,但这样我就没有了
getLog()
方法…)