Rubyで多重継承を実現する!初心者でもわかる5つのステップ

Ruby多重継承解説のイラストRuby
この記事は約7分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

プログラミング言語Rubyで多重継承を実現する方法について考えたことはありますか?

多重継承は一見複雑に見えますが、実際にはわずか5つのステップを理解すれば誰でも利用できます。

この記事では、その5つのステップを具体的なサンプルコードとともに紹介します。

●Rubyと多重継承

Rubyは、オブジェクト指向プログラミング言語の一つであり、クラスによる継承をサポートしています。

しかし、多重継承、つまり一つのクラスが複数のクラスから継承することは基本的にサポートしていません。

その代わり、Rubyではモジュールという機能を用いて、同様の目的を達成します。

○多重継承とは

多重継承とは、一つのクラスが複数の親クラスから属性やメソッドを継承することを指します。

これにより、異なるクラスが持つ機能を一つのクラスに集約することが可能となります。

○Rubyの多重継承の特徴

Rubyの多重継承は、モジュールという機能を通じて実現されます。

モジュールはクラスと似た構造を持ち、メソッドや定数を定義することができます。

これらのモジュールをクラスにインクルードすることで、そのクラスはモジュールが持つメソッドや定数を利用できるようになります。

●多重継承の実装

Rubyで多重継承を実装するには、モジュールを作成し、それをクラスにインクルードする方法を採ります。

○モジュールの利用

モジュールは、関連性のあるメソッドや定数をまとめるための仕組みです。

クラスと同じように、モジュール内にメソッドを定義することができます。

□サンプルコード1:基本的なモジュールの作成と利用

次のコードは、モジュールを作成し、それをクラスにインクルードする基本的な例を示しています。

module Speak
  def speak
    puts 'こんにちは!'
  end
end

class User
  include Speak
end

user = User.new
user.speak # "こんにちは!"と出力されます。

このコードでは、Speakという名前のモジュールを作成し、speakというメソッドを定義しています。

そして、Userというクラスを作成し、Speakモジュールをその中にインクルードしています。

この結果、Userクラスのインスタンスはspeakメソッドを使用することができます。

この例ではUser.newでUserクラスの新しいインスタンスを作成し、speakメソッドを呼び出すことで、「こんにちは!」と出力しています。

□サンプルコード2:モジュールを使った多重継承の実現

では、次に多重継承を模擬するために、複数のモジュールを一つのクラスにインクルードする例を見てみましょう。

module Speak
  def speak
    puts 'こんにちは!'
  end
end

module Walk
  def walk
    puts '歩いています。'
  end
end

class User
  include Speak
  include Walk
end

user = User.new
user.speak # "こんにちは!"と出力されます。
user.walk # "歩いています。"と出力されます。

このコードでは、Speakモジュールとは別にWalkというモジュールを定義し、それぞれのモジュールで異なるメソッドを定義しています。

その後、Userクラスでこれらのモジュールをインクルードしています。

これによりUserクラスのインスタンスは、Speakモジュールのspeakメソッドと、Walkモジュールのwalkメソッドの両方を使用することができます。

●応用:さらなる機能の追加

モジュールを利用することで、Rubyのクラスにさらなる機能を追加することが可能です。

さらに深く掘り下げてみましょう。

○サンプルコード3:追加機能の実装

下記のサンプルコードでは、新たなモジュール「Run」を作成し、その中でrunメソッドを定義し、Userクラスに追加しています。

module Speak
  def speak
    puts 'こんにちは!'
  end
end

module Walk
  def walk
    puts '歩いています。'
  end
end

module Run
  def run
    puts '走っています。'
  end
end

class User
  include Speak
  include Walk
  include Run
end

user = User.new
user.speak # "こんにちは!"と出力されます。
user.walk  # "歩いています。"と出力されます。
user.run   # "走っています。"と出力されます。

このコードでは、既存のSpeakモジュールとWalkモジュールに加えて、Runモジュールを新たに定義しています。

その後、Userクラスでこれらのモジュールすべてをインクルードしています。

この結果、Userクラスのインスタンスは、Speakモジュールのspeakメソッド、Walkモジュールのwalkメソッド、そしてRunモジュールのrunメソッドを使用することができます。

新たに追加したrunメソッドを呼び出すと、「走っています。」と出力されます。

●多重継承の注意点と対処法

多重継承(Rubyの場合はモジュールの利用)を活用する上で、注意すべきポイントがいくつか存在します。

ここでは、それらの注意点とその対処法について解説します。

○注意点1:メソッドの衝突

多重継承を利用する際、一つのクラスが複数のモジュールをインクルードすると、同名のメソッドが複数のモジュールで定義されている場合、どのモジュールのメソッドが使用されるのかが問題となります。

これは「メソッドの衝突」と呼ばれ、プログラミング上のエラーを引き起こす可能性があります。

対処法としては、メソッド名を一意にする、あるいは意図的に特定のモジュールのメソッドを優先させるといった工夫が必要となります。

Rubyでは後にインクルードされたモジュールのメソッドが優先されます。

○注意点2:継承チェーンの理解

Rubyでは、メソッド呼び出し時に、そのメソッドが定義されている場所を探すために「継承チェーン」または「メソッドルックアップパス」と呼ばれる探索順序が存在します。

モジュールを利用した多重継承では、この継承チェーンが複雑化するため、どのメソッドが呼ばれるのか把握することが難しくなります。

継承チェーンを理解し、適切にコードを組むことで、意図しない動作を避けることができます。

●カスタマイズ方法

次に、Rubyで多重継承を利用したカスタマイズの方法を紹介します。

下記のサンプルコードでは、モジュール内で定義したメソッドを上書きし、カスタマイズしています。

○サンプルコード4:独自のカスタマイズ例

module Speak
  def speak
    puts 'こんにちは!'
  end
end

class User
  include Speak

  def speak
    puts 'おはようございます。'
  end
end

user = User.new
user.speak # "おはようございます。"と出力されます。

このコードでは、UserクラスでSpeakモジュールをインクルードした上で、speakメソッドを再定義しています。

その結果、Userクラスのspeakメソッドが呼び出されると、「おはようございます。」と出力されます。

これは、Userクラスで再定義したspeakメソッドが、Speakモジュールのspeakメソッドを上書きしているからです。

まとめ

以上が、Rubyでの多重継承の実現方法と、その使い方、注意点などを初心者でも理解できるように解説してきました。

サンプルコードを参考にしながら、自分だけの機能を作り出すために、ぜひともこの知識を活用してみてください。

最初は難しく感じるかもしれませんが、一つずつ理解を深めていくことで、Rubyの可能性がさらに広がることでしょう。