ゆーたんのつぶやき

株式会社ノークリサーチにてIT関連のシニアアナリストとして活動しています。

メソッドオーバーライドとTemplateMethodパターン



昨日の続きのような感じになりますが、C#ではメソッドのオーバーライド
について細かい制御ができるのが便利ですね。Javaの場合にはメソッドは
すべてC#で言うところのvirtualがついた状態になってしまいます。 つまり
強制的に仮想関数になってしまうわけですね。C#の場合は仮想関数とす
るのか、シグネチャは同じだけれども別物とみなすのかの制御をoverride
/newで指定することができます。


本来、「メソッドが継承可能か?」という概念と「メソッドが何処から呼び出し
可能か?」という概念は別のものであるはずです。ですが、Javaの場合には
protectedの意味が「継承可能である」という意味と「サブクラスからアクセス
可能」という意味の二つを同時に持っているので、ちょっと面倒なことになります。


具体的に困る場面はTemplate Methodパターンを適用したケースなどです。


public final void templateMethod(){
 overrideMethod();
}
protected void overrideMethod(){
 /* 書き換えるメソッド */
}


上のコードではoverrideMethod()はオーバーライドされることを想定して
いますが、呼び出しは必ずtemplateMethod()を通じて行われる必要があり
ます。ですが、サブクラスを書いた人がデザインパターンの前提に反して
誤ってoverrideMethod()を直接呼び出してしまう危険性があるわけです。


C#の場合を試してみましたが、やはり「オーバーライドは許すけれども
特定のメソッド内でのみ呼び出し可能なメソッド」というものを作成す
ることはできないようです。言語仕様として本当に必要かどうかはわか
りませんが、internal/private/protected/publicといった既存のスコ
ープ指定に加えて、「特定のメソッド内でのみ参照可能」という指定が
できると上記のようなリスクは減るかも知れません。