【Ruby】レッスン5-07:クラスの継承を理解しよう

記事内に商品プロモーションを含む場合があります

この記事で学べる知識:クラスの継承

この記事の練習問題を解くために必要な知識:
基礎文法、制御構造、メソッド、コレクション(レッスン1~4)クラスの定義と使用イニシャライザアクセスメソッドクラス変数とクラスメソッドprivateメソッド正規表現クラスの継承ファイル操作オーバーライドモジュールの定義と使用ミックスイン

<<前のページ Ruby記事一覧 次のページ>>

Rubyの「クラスの継承」とは

ここではクラスの継承の意味や使い方を学習します。必要ない方はここ

クラスの継承とは他のクラスの機能を引き継ぎ再利用できる仕組みです。

これはオブジェクト指向プログラミング(OOP)の中核となる概念の一つです。

【初心者向け】Rubyのオブジェクト指向を分かりやすくまとめた概念図。 特にクラスの継承、オーバーライド、モジュール、ミックスイン、インスタンス生成の関係性を視覚的に理解できるようまとめている。

継承とは?

継承は基本となる「親クラス」から機能を受け継ぐ「子クラス」を定義する方法です。

この仕組みを使うことで、共通の処理を親クラスにまとめ、コードの再利用性を向上させることができます。

例えば多くのクラスで似たような振る舞いを実装する際、親クラスにその振る舞いをまとめることで、重複を防ぐことが可能です。

また子クラスは親クラスのメソッドや属性をそのまま使えるほか、独自の機能を追加することもできます。

基本的な構文

Rubyではクラスを継承する際に親クラス名を < を使って指定します。

構文は次のとおりです。

class 子クラス名 < 親クラス名
  # 子クラスの独自のメソッドやプロパティ
end

例えば以下のようなコードが考えられます。

class Animal # 親クラスの定義
  def speak
    puts "動物の鳴き声"
  end
end

class Dog < Animal # Animalクラスを継承するDogクラス(子クラス)の定義
end

この例ではDog クラスは Animal クラスを継承しています。

Dog クラスは特別なコードを追加していなくても、Animal クラスで定義されたメソッドを使用することができます。

使用例

継承を利用する実例を見てみましょう。

class Animal # 親クラスの定義
  def initialize(name)
    @name = name
  end

  def speak
    puts "#{@name}は音を出します。"
  end
end

class Dog < Animal # Animalクラスを継承したDogクラスの定義
end

class Cat < Animal # Animalクラスを継承したCatクラスの定義
end

dog = Dog.new("ポチ") # インスタンス生成
cat = Cat.new("タマ") # インスタンス生成

dog.speak # Dogクラスは親クラスのspeakメソッドを使用できる。
cat.speak # 同上。出力:タマは音を出します。

この例ではDog クラスと Cat クラスは、それぞれ親クラスである Animal クラスを継承しています。

initialize メソッドや speak メソッドを子クラスで特別に書かなくても、親クラスで定義されたものをそのまま使用できます。

継承を使うメリット

  1. コードの再利用性:
    共通のコードを親クラスにまとめることで、子クラス間で重複を避けられます。
  2. 保守性の向上:
    親クラスを変更すればその変更が全ての子クラスに反映されるため、メンテナンスが容易になります。
  3. 柔軟性の向上:
    子クラスで独自の振る舞いを追加することで、柔軟に機能を拡張できます。

ただし継承を多用しすぎると設計が複雑になり、意図しない動作の原因となる場合があります。

適切な設計を心がけましょう。

まとめ

Rubyのクラスの継承はコードを効率化し、保守性を高める強力な手法です。

親クラスを通じて共通の機能を管理し、子クラスで必要な場面に応じた機能を持たせることで、柔軟かつ整理されたコードを書くことができます。

適切な場面で活用することで、学習が進んだ際により高度な設計をスムーズに理解する助けになります。

クラスの継承の確認問題

Rubyの「クラスの継承」の仕組みを使って、動物と犬をモデルにしたプログラムを作成してみましょう。

このプログラムでは動物クラスを親クラスとし、その機能を犬クラスで拡張します。

動物クラスには挨拶を行う機能を持たせ、犬クラスには特有の「吠える」機能を追加します。

それぞれのクラスを使ったインスタンスを作成し、適切なメソッドを呼び出して動作を確認してください。

この問題の要件

以下の要件に従ってコードを完成させてください。

  1. 動物クラスを作成し、以下を実装すること。
    • initializeメソッドで名前を受け取り、それをインスタンス変数@nameに格納すること。
    • greetメソッドを作成し「こんにちは!私は○○です。」という形式で名前を表示すること。
  2. 犬クラスを作成し、動物クラスを継承すること。
    • barkメソッドを作成し「○○はワンワンと吠えます。」という形式で出力すること。
  3. 動物クラスのインスタンスを作成しgreetメソッドを呼び出すこと。
  4. 犬クラスのインスタンスを作成し以下を実行すること。
    • 継承したgreetメソッドを呼び出すこと。
    • 独自に定義したbarkメソッドを呼び出すこと。

ただし、以下のような実行結果となること。

----- ↓出力される結果の例↓ -----

こんにちは!私は一般的な動物です。
こんにちは!私はポチです。
ポチはワンワンと吠えます。

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。

1:Animalクラスを定義
  □ initializeメソッドを定義し、名前を受け取りインスタンス変数@nameに格納
  □ greetメソッドを定義し、インスタンス変数@nameを使用して挨拶文を出力

2:Animalクラスを継承してDogクラスを定義
  □ barkメソッドを定義し、インスタンス変数@nameを使用して吠えるメッセージを出力

3:Animalクラスのインスタンスを作成し、「一般的な動物」を名前に設定
  □ animalオブジェクトのgreetメソッドを呼び出し、挨拶文を出力

4:Dogクラスのインスタンスを作成し、「ポチ」を名前に設定
  □ dogオブジェクトのgreetメソッドを呼び出し、Animalクラスの挨拶文を出力
  □ dogオブジェクトのbarkメソッドを呼び出し、Dogクラス特有の吠えるメッセージを出力

ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

# 動物クラスを定義します。
class Animal
  # 初期化メソッドで名前を設定します。
=begin
【穴埋め問題1】
ここにinitializeメソッドを定義し、名前を受け取りインスタンス変数@nameに格納するコードを書いてください。
=end

  # 動物が挨拶をするメソッド
=begin
【穴埋め問題2】
ここにgreetメソッドを定義し、「こんにちは!私は○○です。」という形式で名前を表示するコードを書いてください。
=end
end

# 動物クラスを継承して犬クラスを作成します。
=begin
【穴埋め問題3】
ここにDogクラスを作成し、Animalクラスを継承するコードを書いてください。
=end

  # 犬専用のメソッドを定義します。
=begin
【穴埋め問題4】
ここにbarkメソッドを定義し、「○○はワンワンと吠えます。」という形式で出力するコードを書いてください。
=end
end

# 動物クラスのインスタンスを作成します。
animal = Animal.new("一般的な動物")
animal.greet # 動物クラスの挨拶メソッドを呼び出します。

# 犬クラスのインスタンスを作成します。
dog = Dog.new("ポチ")
dog.greet # 親クラス(Animal)の挨拶メソッドを使用します。
dog.bark  # 子クラス(Dog)の専用メソッドを使用します。

この問題の穴埋めコードは以上です。

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。



練習問題の解答と解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

# クラスの継承について学ぶためのサンプルコード
# クラスの基本と継承を使って、動物と犬の例を示します。

# 動物クラスを定義します。
class Animal
  # 初期化メソッドで名前を設定します。
  def initialize(name)
    @name = name
  end

  # 動物が挨拶をするメソッド
  def greet
    puts "こんにちは!私は#{@name}です。"
  end
end

# 動物クラスを継承して犬クラスを作成します。
class Dog < Animal
  # 犬専用のメソッドを定義します。
  def bark
    puts "#{@name}はワンワンと吠えます。"
  end
end

# 動物クラスのインスタンスを作成します。
animal = Animal.new("一般的な動物")
animal.greet # 動物クラスの挨拶メソッドを呼び出します。

# 犬クラスのインスタンスを作成します。
dog = Dog.new("ポチ")
dog.greet # 親クラス(Animal)の挨拶メソッドを使用します。
dog.bark  # 子クラス(Dog)の専用メソッドを使用します。

正解コードの解説

今回のRubyコードでは「クラスの継承」の仕組みを学びます。

動物クラスを親クラス(Animal)として定義し、それを継承する子クラス(Dog)を作成することで、コードの再利用と拡張性の利点を確認します。

以下、各ブロックの内容を初心者向けに解説します。

動物クラスの定義

class Animal
  def initialize(name)
    @name = name
  end

  def greet
    puts "こんにちは!私は#{@name}です。"
  end
end
  • class Animal
    Animalという名前のクラスを定義します。クラスはオブジェクトの設計図で、データとその動作をまとめます。
  • def initialize(name)
    初期化メソッド(コンストラクタ)です。インスタンスが作成されるときに名前を引数として受け取り、@nameというインスタンス変数に格納します。
  • def greet
    greetメソッドではputsを使ってインスタンスの名前を含む挨拶文を出力します。#{@name}でインスタンス変数を文字列の中に埋め込みます。

犬クラスの定義

class Dog < Animal
  def bark
    puts "#{@name}はワンワンと吠えます。"
  end
end
  • class Dog < Animal
    DogクラスはAnimalクラスを継承しています。<記号を使うことで、Animalクラスのメソッドやデータをそのまま利用できます。
  • def bark
    barkメソッドは犬特有の動作を定義しています。このメソッドではputsを使い、名前と「吠える」メッセージを出力します。
  • ポイント:
    Animalクラスを継承することで名前の設定や挨拶機能を再実装する必要がなくなり、新しい機能(barkメソッド)を追加するだけで済みます。

動物と犬のインスタンスを作成

animal = Animal.new("一般的な動物")
animal.greet

dog = Dog.new("ポチ")
dog.greet
dog.bark
  • animal = Animal.new("一般的な動物")
    Animalクラスのインスタンスを作成します。このインスタンスは「一般的な動物」という名前を持ちます。
  • animal.greet
    Animalクラスのgreetメソッドを呼び出して挨拶文を出力します。
  • dog = Dog.new("ポチ")
    Dogクラスのインスタンスを作成します。「ポチ」という名前を持つ犬になります。DogクラスはAnimalクラスを継承しているため、initializeメソッドは再利用されています。
  • dog.greet
    Dogクラスのインスタンスでありながら、親クラスであるAnimalのgreetメソッドを呼び出します。
  • dog.bark
    Dogクラス独自のbarkメソッドを呼び出して、吠えるメッセージを出力します。

まとめ

このコードでは、Rubyの「クラス」と「継承」を学びました。

継承を利用することで共通する機能を親クラスにまとめ、子クラスで独自の機能を追加できます。これによりコードの再利用性と可読性が向上します。

この仕組みを理解することで、現実世界のオブジェクトをプログラムで表現しやすくなります。

ぜひ自分で別の動物クラスや機能を追加してみて、継承の利便性を体験してください!

<<前のページ Ruby記事一覧 次のページ>>

この記事への質問・コメント

この記事を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    Rubyテキスト&問題集へ戻る
    トップページへ戻る