北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

継承し過ぎ

メソッドのオーバーライドを用いて共通ロジックをまとめているコードがあったんだけど、これをやると不自然なスーパークラスが出来上がってしまうことがある。



sentenceと言う文章を出力するメソッドを持つSub1クラスがあったとき、Sub1と言うクラスを継承して「いつも〜」と言う文章を吐くSub1Alwaysクラスを作ると、



package Sub1Always;
use base qw{Sub1};
sub sentence{
print "いつも?n";
shift->SUPER::sentence();
}





こんな感じになり、これは自然な継承に見える。



では、どんな場合に不自然な継承になるのか。Sub1とSub2と言うBaseクラスのサブクラスで、「perlを使って」と言う共通部分を見つけた人が、「それならBaseのクラスのsentenseにこの部分だけを押し込めるとSub1とSub2で使えて共通化できるじゃないか」、と発想した場合の以下のコード。



package Base;
sub sentence{
print "perlを使って?n";
}

package Sub1;
use base qw{Base};
sub sentence{
print "私は?n";
shift->SUPER::sentence();
print "います?n";
}

package Sub2;
use base qw{Base};
sub sentence{
print "あなたは?n";
shift->SUPER::sentence();
print "いません?n";
}






Sub1とSub2はクラスのsentenceメソッドの恩恵を受けれるし問題ないように見えるのだが、Baseクラスのsentenceメソッドが「perlを使って」と言う句を返すだけの関数となってしまい、sentenceメソッドとして不完全である。



継承は設計上必要な場合だけに抑えておかないと、上述のパターンのように不自然なクラスが出来上がってしまうことがあるので、注意が必要だ。