Rubyの基礎(「クラスの継承」の観点からオブジェクト指向を考えてみた)


Rubyって?

まつもとゆきひろ氏(通称Matz)によって開発されたオブジェクト指向スクリプト言語。
2004年にはRubyを使ったWebアプリケーションフレームワークのRuby on Railsが登場して一気に世界に普及

オブジェクト指向って?

オブジェクト指向とは、オブジェクト同士の相互作用として、システムの振る舞いをとらえる考え方
(Wikipedia)

オブジェクト指向プログラミング(Object Oriented Programming: OOP)とは、プログラムを手順ではなくて、モノの作成と操作として見る考え方だ。
https://eng-entrance.com/what-oop

明確な定義は決まってないっぽい。、まだプログラミング学習始めて1ヶ月で理解が浅すぎるが、クラスの継承の観点から自分なりに「全てのデータはObjectクラスのオブジェクト・インスタンスだから」と解釈した。

以下、頭の中を整理してみた。

クラスとメソッド

クラス

クラスは自身で定義した設計図に基づいて生成されたデータ(オブジェクト)を内部に持っており、そのデータを利用するための独自の使用方法(メソッド)を持つことができる。つまり、データの設計図の役割とその使用方法を整理できる便利ツール。クラスは設計図に基づいたデータ(オブジェクト)を作成することができる。全てのデータ(オブジェクト)は何かしらのクラスの設計図に基づいて作られたものなので、必ず何かしらのクラスに属している。

オブジェクト(インスタンス、レシーバ)

クラスに定義された設計図に基づいて作られたデータをオブジェクト(インスタンス、レシーバ)と呼ぶ。同じ設計図(クラス)から作られたデータは同じ属性(データ項目、オブジェクトが持つ情報の種類)やメソッド(使用方法)を持つ。データ内容自体はクラス外で付与するので、作られたデータによってそれぞれ異なるデータ内容を持っている。
呼び方が複数あるが、「インスタンス」はクラスの視点から見た用語で、「レシーバー」はメソッドの視点から見た用語。
「インスタンス」と呼ぶ場合は,(たとえあらわに書いてなくても)必ず何らかのクラスが想定されていて、「○○のインスタンス」として使われる。また、「レシーバー」と呼ぶ場合は必ず何らかのメソッドが想定されていて、そのメソッドが呼び出される対象のオブジェクトを指している。

「オブジェクト」「インスタンス」「レシーバー」はそれぞれ「物(ブツ)」「クラスから生成された具現物」「メソッドの受け手」のようなイメージ

class Review

end
review = Review.new(引数) # Reviewクラスのオブジェクト・インスタンスを生成

メソッド(使用方法)

使用方法、処理をひとまとめにして名前を付けて、何回も再利用できるようにしたもの。

メソッド(使用方法)の定義

■クラスメソッド:クラス自身(self)が持っているメソッド。

class クラス名
  def self.メソッド名
    # 処理
  end
end

# メソッドの呼び出し
クラス名.メソッド名(引数)

■インスタンスメソッド:クラスから生成されたインスタンスが使用できるメソッド。インスタンスごとの個別の情報(属性値)を使った処理に使用
例えば「レビューの内容を表示する」メソッドは、各レビューのインスタンスの個別の情報((属性値)を使用するので、インスタンスメソッドとして定義。

class クラス名
  def メソッド名
    # 処理
  end
end

# メソッドの呼び出し
インスタンス.メソッド名(引数)

変数

■クラス変数(@@変数名):クラス全体で使用できる変数。クラス内であればどこでも使えるのでクラスメソッド、インスタンスメソッドの両方で使うことが出来る。クラスを通して、値が共通の情報に使用。

■インスタンス変数(@変数名):共通の属性としてインスタンスに定義できる変数。値は、個々のインスタンスによって別々に設定できる。例えばタイトルや感想は、各レビューごとに内容が異なる。つまり、インスタンスごとに値が異なる情報。よってインスタンス変数を使用

class クラス名
  def write_review
    puts "タイトルを入力してください"
    @title = gets.chomp
    puts "ジャンルを入力してください"
    @genre = gets.chomp
    puts "感想を入力してください"
    @impression = gets.chomp
  end
end

クラスの継承

あるクラスに定義されたメソッドを、別のクラスで利用出来るようにすることを継承と言う。

クラスの継承には、親クラスと子クラスの関係があり、元となるクラスを親クラス(スーパークラス)、親クラスのメソッドを引き継ぎ新しく作成するクラスを子クラス(サブクラス)と呼ぶ。

継承方法
class 子クラス名 < 親クラス名

継承するかどうかのポイントは性質や概念が共通しているか、「is-aの関係」が成立するかどうか
言い換えると「サブクラスはスーパークラスの一種である」、もっと具体的に言うと、「犬は動物の一種である」という関係がスーパークラスとサブクラスの間に成立しているかどうかが継承の判断基準になる。

基本的にRubyの継承は単一継承で、継承できるスーパークラスは1つだけ。
クラスはRubyに標準装備されているものがある。例えば文字列はStringクラス、数値はNumericクラス、配列はArrayクラス、ハッシュはHashクラスである。これらは標準装備されているので、クラスを定義せずとも、オブジェクトやそれに付随したメソッドを使用することができる。

これら標準装備のクラス(ライブラリ)の継承関係を見ると、トップに君臨しているのがBasicObjectクラス
これはRuby1.9から導入されたクラスでそれまでは、Objectクラスがトップに君臨していた。図を見ると、一目瞭然だが、Stringクラス、Numericクラス、Arrayクラス、Hashクラスは全てObjectクラスをスーパークラスとして継承したサブクラスである。この図を言い換えると、Rubyにおける全てのデータはObjectクラスのオブジェクト・インスタンスと言える。

だから、Rubyはオブジェクト指向の言語って言うのかな? と勝手に考えてました。