1

派生クラスに独自のロガーを持たせたいのですが、できないようです:

abstract class C {
  final protected static Logger l;
  C (...) {
    l.emit("C");
  }
}
class C1 extends C {
  final protected static Logger l = new Logger("C1");
  C1 (...) {
    super(...);
    l.emit("C1");
  }
}

inではなく in がLogger必要なため、次の出力が生成されます。C1Cnew C1()

C1: C
C1: C1

(最初の行はCコンストラクターから、2 行目はC1コンストラクターから取得されます)。代わりに があるのでnullPointerException、私は入ります。Clnull

inにすることはできません。出力が次のようになるため、そこで初期l化したくありませんabstractC

C: C
C1: C1

私のオプションは何ですか?

ありがとう!

4

2 に答える 2

6

ソリューション1(クラシック)

考えられるアプローチはgetLogger()、抽象クラスに抽象メソッドを含めることです。これにより、派生クラスは独自のロガーを提供するように強制されます。

public class AbstractClass {
  abstract Logger getLogger();

  public void someMethodInAbstractClass() {
    getLogger().debug("something"); // will output using provided child logger
  }
}

public class ConcreteClass extends AbstractClass {
  private static final Logger LOGGER = Logger.getLogger(ConcreteClass.class);

  @Override
  Logger getLogger() {
    return (LOGGER);
  }

  public void someMethod() {
    getLogger().debug("something"); // will output using local logger
  }
}

抽象クラスにデフォルトの実装を提供して、子にオーバーライドを実装させないようにすることもできます。抽象クラスのコンシューマー(具象クラスの開発)を簡単にしますが、メソッドの細粒度を強制することはありません。

解決策2(長蛇の列...)

もう1つのより暴力的な解決策はgetMagicLogger()、抽象クラスにメソッドを含めることです。このメソッドは、実行時に現在のインスタンスの具体的なタイプを決定して、毎回、または遅延ロードしてフィールドに格納することにより、新しいロガーインスタンスを返します。

このように、抽象クラスはそれをすべて処理し、消費者にとっては非常に簡単ですが、それは一種のクレイジーなことです。そして、それは明らかに、ロガーが静的フィールドではないことを意味します。

于 2012-06-07T18:33:57.130 に答える
4

静的メンバーをオーバーライドする属性はありません。のlロガーはでC宣言されたものC(null)であり、サブクラスのロガーではありません。C1

于 2012-06-07T18:35:35.280 に答える