Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Ruby応用 | 多重継承

パンくず

Ruby応用
多重継承

概要

多重継承について

単一継承と多重継承

・単一継承は機能としては多重継承に劣るがシンプル
二つのクラスを継承したい場合は、苦し紛れな手段で疑似的な
継承をせざるを得ない
片方を継承して、片方のコードをコピーor異常+ラッピングして実装したり。

その代わりに継承構造がシンプルな木構造になるため分かりやすい

・多重継承は機能として単一継承に勝るが複雑
上記のようなケースは多重継承であれば簡単に実現出来ます。
その代わり、継承構造がネットワークの網の目のようになり複雑で
問題が発生した場合に原因を特定するのが困難になる。

多重継承の問題点

構造の複雑化
機能の衝突:複数基底クラスに同じ振る舞いや属性がある場合
継承の優先順位が決まらない

継承の種類

実装の継承:extends
仕様の継承:implements

Javaの場合、仕様は複数継承できるが実装は単一継承です。
Rubyの場合、仕様の継承という概念そのものがない
Rubyの多重継承はModuleを使用したMix-inで行う

Mix-inクラスは以下のような特徴を備えた抽象クラスです。

Mix-inの特徴

インスタンスを作成できない
継承できない

Mix-inのサンプル

module TestDriven
  def test_driven_coding()
    puts "テスト駆動"
  end
end

class Programmer
  attr_accessor:name
  def initialize(name)
    @name=name
  end

  def coding()
    puts "コーディング"
  end
end

class JavaProgrammer < Programmer
  LANGUAGE="Java"
  def coding()
    puts "Javaのコーディング"
  end
  include TestDriven
end

class RubyProgrammer < Programmer
  LANGUAGE="Ruby"
  def coding()
    puts "Rubyのコーディング"
  end
  include TestDriven
end

programmers = [JavaProgrammer.new("田中"), RubyProgrammer.new("鈴木")]
programmers.each {|programmer|
  puts "---------------#{programmer.class::LANGUAGE}---------------"
  programmer.coding
  programmer.test_driven_coding
}

結果

---------------Java---------------
Javaのコーディング
テスト駆動
---------------Ruby---------------
Rubyのコーディング
テスト駆動