第12章 継承の取り扱い

メソッドの引き上げ

これを適用する最も単純なケースは、二つ以上のメソッドが同じ内容を持ち、コピペが行われたことを暗示される場合

要はサブクラスで共通しているメソッドなら、スーパークラスに持っていこうということ

手順

フィールドの引き上げ

フィールドが同じように使われているなら、スーパークラスに引き上げることで二つの面で重複を減らせる

手順

コンストラクタ本体の引き上げ

コンストラクタを引き上げる場合、順序の問題などがあつため、少し違ったアプローチが必要になる
このリファクタリングが混乱し始めた時は、ファクトリ関数によるコンストラクタの置き換えを試みる

手順

メソッドの押し下げ

あるメソッドが一つ(少数)のサブクラスだけに関わる処理を行なっている場合、そのメソッドをスーパークラスから取り除き、サブクラスに持っていくことでクラス構造が明確になる
呼び出し先が特定のサブクラスに限定されている場合のみ可能、それ以外の場合はポリモーフィズムによる条件記述の置き換えを適用する

手順

フィールドの押し下げ

メソッドの押し下げのフィールド版

手順

サブクラスによるタイプコードの置き換え

類似しているが少し違うものを表現したいときに、多くの場合はタイプコードだけで事足りる
しかしサブクラスを使うと、二つ嬉しいことがある

手順

サブクラスの削除

サブクラスが結局使われなかったり、小さすぎて存在価値がない場合にサブクラスを取り除いて、スーパークラスのフィールドに置き換えるなどをする

手順

スーパークラスの抽出

二つのクラスが同じようなことをしていたら、継承の基本的なメカニズムを使って類似点をスーパークラスにまとめてしまう

手順

クラス階層の平坦化

クラス階層のリファクタリングをした結果、あるクラスとその親クラスの間に別クラスに分けるほどの差がなくなることがある
この場合、一つにマージする

手順

委譲によるサブクラスの置き換え

継承の場合、一軸でしかバリエーションを持たせられず、密結合することでするなどのデメリットがある
軽症で問題が発生したら、委譲によるサブクラスの置き換えをすることで解決することがある

手順

委譲によるスーパークラスの置き換え

スーパークラスの処理がサブクラスにおちえ、適合しない場合に行う
例として挙げていたのが、StackをListのサブクラスにしたこと

手順

感想

継承関係は結構複雑になるのはわかる
特にフレームワーク側が勝手にやってしまう場合はどうしたらいいんだろう