【Ruby入門】クラスを作る!メソッドの違いやアクセサを覚える【#8】


こんにちは。Tomoyuki(@tomoyuki65)です。

オブジェクトやクラスについては、結構理解しづらいですよね。

特にクラスはオブジェクト指向のプログラミングにとって必須です。

 

でも、クラスは作ってみると結構簡単なんですよ。

 

この記事では、そんなクラスの作り方について解説します。

 



メソッドの作り方

クラスを作る為に、まずはメソッドの作り方を学びましょう。

メソッドは何らかの役割や処理が出来る関数のようなものです。

メソッドは以下のように書きます。

def メソッド名
  処理
end

# メソッドを実行する場合
メソッド名

 

では以下のプログラムを実行してみて下さい。

# メソッドの定義
def say
  puts "こんにちは!"
end

# メソッドを実行する場合
say

 

実行結果
こんにちは!

 

メソッドにオプションを持たせる場合

メソッドにはオプションを持たせることができます。

オプションの書き方は、メソッド名の後に()を付け、()の中に変数を記載します。

この変数のことを引数と呼び、引数はカンマ区切りで複数持たせることができます。

 

では以下のプログラムを実行してみて下さい。

# 引数name
def say(name)
  puts "#{name}さん こんにちは!"
end

# メソッドを実行
say("田中")

# 意味が曖昧にならない場合は()は省略できます。
say "田中"

 

実行結果
田中さん こんにちは!
田中さん こんにちは!

 

引数を複数持たせた場合

# カンマ区切りで引数を複数持たせることができる
def say(name1, name2)
  puts “#{name1}さん、#{name2}さん こんにちは!”
end

 

say(“佐藤さん”, “木村さん”) # ()は省略可能

 

# 実行結果 => 佐藤さん、田中さん こんにちは!

 

メソッドの引数にデフォルト値を持たせる場合

メソッドの引数にはデフォルト値を持たせることができます。

では以下のプログラムを実行してみて下さい。

# 引数nameにデフォルト値「"山田"」を持たせる場合
def say(name = "山田")
  puts "#{name}さん こんにちは!"
end

# メソッドを実行
say

 

実行結果
山田さん こんにちは!

 

メソッドに値を返してもらいたい場合

メソッドは最後に評価した値を返します。

したがって、以下のように書くと値を返すことができます。

# 引数nameにデフォルト値「"山田"」を持たせる場合
def say(name = "山田")
  "#{name}さん こんにちは!"
end

# 返ってきた値をpメソッドで出力
p say

 

実行結果
山田さん こんにちは!

 

明示的に返す値を指定したい場合

def say(name = “山田”)
  return “#{name}さん こんにちは!”
end

 

# 返ってきた値をpメソッドで出力
p say

 

メソッド内で定義した変数について

メソッド内で定義した変数には、外からアクセスできないというルールがあります。

例として以下のプログラムを実行してみて下さい。

def say(name = "山田")
  num = 100
  "#{name}さん こんにちは!"
end

# メソッド内で定義した変数numを指定
p num

 

実行結果
undefined local variable or method `num’ for main:Object (NameError)

 

実行結果の通り、メソッド内で定義した変数にはアクセスできないため、エラーメッセージが出力されます。

 



クラスの作り方

メソッドの作り方を理解したところで、クラスを作ってみましょう。

クラスは以下のように書きます。この時、クラス名の最初の文字は必ず大文字である必要があります。

class クラス名
  メソッドなどを記載
end

 

例として、Userクラスを作りましょう。Userクラスには「こんにちは!」と表示するsayメソッドを持たせます。

では以下のプログラムを実行してみて下さい。

# クラスの定義
class User
  def say
    puts "こんにちは!"
  end
end

# 「tanaka」というインスタンスを作成
tanaka = User.new

# メソッド「say」を実行
tanaka.say

 

実行結果
こんにちは!

 

インスタンス内の変数に値を保持する方法

次にクラスを拡張してみます。

インスタンス内の変数に値を保持するため、インスタンス作成時に呼ばれる特殊なメソッド「initialize」を追加します。

では以下のプログラムを実行してみて下さい。

# インスタンス作成時、インスタンス変数に名前を保持させる
class User
  # initializeメソッドを定義。インスタンス作成時に実行されます。
  def initialize(name)
    # インスタンス変数には頭に@を付ける
    @name = name
  end

  def say
    # 文字列の中でインスタンス変数「@name」を展開
    puts "#{@name}さん こんにちは!"
  end
end

# インスタンスを作成時に文字列「"田中"」を渡す
tanaka = User.new("田中")

# メソッド「say」を実行
tanaka.say

# もう一つインスタンスを作成した場合
satou = User.new("佐藤")
satou.say

 

実行結果
田中さん こんにちは!
佐藤さん こんにちは!

 

先ほどメソッド内で定義した変数は外からアクセスできないというルールがありましたが、インスタンス変数は特殊です。

インスタンス内であればどこからでも呼び出すことができ、インスタンスごとに値が保持されます。

 

インスタンス変数へのアクセス

以下の例をみて下さい。

インスタンス変数はインスタンス外からはアクセスできません。

tanaka = User.new("田中")
# このようにインスタンス変数へはアクセスできない
tanaka.name = "山田"
p tanaka.name

 

したがって、上記のようにインスタンス変数の値を変えたり呼び出したい場合は、通常それらを実現するためのメソッドを定義する必要があります。

 

ただし、よく行う処理なのでRubyではアクセサという簡単な記法があります。

例として以下のプログラムを実行してみて下さい。

class User  # アクセサを定義。nameのシンボルを記述
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def say
    puts "#{@name}さん こんにちは!"
  end
end

tanaka = User.new("田中")

# インスタンス変数nameにアクセス
tanaka.name = "山田"
p tanaka.name

 

実行結果
“山田”

 

このようにアクセッサーを定義すると、値をセットするメソッド(setter)と、値を取得するメソッド(getter)が定義されます。

 

「getter」だけを定義したい場合など、アクセサには以下の種類があります。

アクセサの種類

attr_reader :変数名       # 更新可能
attr_writer :変数名        # 参照可能
attr_accessor :変数名   # 参照と更新が可能

 

「self」オブジェクトについて

次はメソッド内で使えるselfオブジェクトについて説明します。

selfはそのメソッドを受け取っているインスタンス自身を指します。

 

例として、以下のプログラムを実行してみて下さい。

class User
  # @nameのsetterとgetterが定義される
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def say    # ここでselfオブジェクトを使った場合、
    # メソッドを受け取っているインスタンス自身を指す。
    puts "#{self.name}さん こんにちは!"

    # 意味が曖昧にならなければ、selfは省略可能
    puts "#{name}さん こんにちは!"
  end

end

tanaka = User.new("田中")
tanaka.name = "山田"

tanaka.say  # メソッドを受け取っているインスタンスをレシーバーと呼びます。

 

実行結果
山田さん こんにちは!
山田さん こんにちは!

 

クラスメソッド

今までクラスで定義してきたメソッドはインスタンスメソッドと呼ばれ、インスタンスから呼び出しました。

その他にも、クラスから直接呼び出すことができるクラスメソッドを定義することもできます。

 

例として以下のプログラムを実行してみて下さい。

class User
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def say
    puts "#{name}さん こんにちは!" 
  end

    # クラスメソッドを定義
  def self.info
    puts "User Classです。"
  end
end

# クラスメソッドを実行
User.info

 

実行結果
User Classです。

 

クラス変数

さらに、クラス変数を定義することでクラス自体に値を保持することもできます。

クラス変数を定義するには、変数の頭に「@@」を付与します。

 

例として、以下のプログラムを実行してみて下さい。

class User
  attr_accessor :name

    # インスタンスの作成数を保持するクラス変数を定義
  @@count = 0

  def initialize(name)
    # newされるたびにカウントアップ
    @@count += 1

    @name = name
  end

  def say
    puts "#{name}さん こんにちは!" 
  end

  def self.info
    # インスタンスの数を出力する。
    puts "User Classです。#{@@count}回インスタンスを作成しました。"
  end
end

# インスタンスを生成
tanaka = User.new("田中")
satou = User.new("佐藤")
suzuki = User.new("鈴木")

# クラスメソッドを実行
User.info

 

実行結果
User Classです。3回インスタンスを作成しました。

 

クラス定数

尚、クラス内では定数も定義できます。

定数は大文字から始めますが、慣習的に全て大文字にするのが推奨されています。

 

では以下のプログラムを実行してみて下さい。

class User
  attr_accessor :name

  @@count = 0

    # 定数を定義
  DESCRIPTION = "ユーザークラス"

  def initialize(name)
    @@count += 1
    @name = name
  end

  def say
    puts "#{name}さん こんにちは!" 
  end

  def self.info
    # 定数も出力する。
    puts "#{DESCRIPTION} User Classです。#{@@count}回インスタンスを作成しました。"
  end
end

# インスタンスを生成
tanaka = User.new("田中")
satou = User.new("佐藤")
suzuki = User.new("鈴木")

# クラスメソッドを実行
User.info

 

実行結果
ユーザークラス User Classです。3回インスタンスを作成しました。

 

クラスの外から定数にアクセスしたい場合は、以下のように「::」を付けて記載します。

# pメソッドでクラス定数を出力
p User::DESCRIPTION

 

# 実行結果 => “ユーザークラス”

 



まとめ

  •  クラス名は大文字から始める
  •  メソッドには引数を持たせることができ、複数持たせるにはカンマで区切る
  •  引数にはデフォルト値を持たせることができる
  •  メソッドは最後に評価した値を返す(明示的にするにはreturnを付ける)
  •  メソッド内で定義した変数には外からアクセスできない(インスタンス変数を除く)
  •  インスタンスの作成は「クラス名.new」で行い、インスタンス作成時には定義したinitializeメソッドが呼ばれる
  •  インスタンス変数は、インスタンス内であればどこからでも呼び出せる
  •  Rubyではアクセサを定義することで、setterやgetterを簡単に定義できる
  •  selfオブジェクトはメソッドを受け取っているインスタンス自身を指し、インスタンスのことをレシーバーと呼ぶ
  •  クラスから直接呼び出すことができるクラスメソッド(self.メソッド名)、クラス変数(@@クラス変数名)や定数も定義できる
  •  クラス内で定義した定数へのアクセスは「クラス名::定数名」で行う

 

今回はクラスの作り方について説明しました。

クラスは奥が深いので、まずは基礎をしっかり押さえましょう!

 

  •  関連記事

【無料あり】Ruby入門サイトおすすめ3選!初心者向けの学習方法を解説

2017年10月24日

【Ruby入門】オブジェクトとは?オブジェクト指向で設計や開発する理由【#3】

2017年7月26日

【Ruby入門】クラスの継承!オーバーライドやアクセス制御【#9】

2017年8月29日

テスト駆動開発を実践!Rubyでテストコードを書きながらクラスを作って遊ぶ!

2017年11月25日

 

The following two tabs change content below.

Tomoyuki

SEを5年経験後、全くの未経験ながら思い切ってブロガーに転身し、月間13万PVを達成。その後コロナの影響も受け、以前から興味があったWeb系エンジニアへのキャリアチェンジを決意。現在はWeb系エンジニアとして働きながら、プロゲーマーとしても活躍できるように活動中。








シェアはこちらから


【2024年】おすすめのゲーミングPC

モンハンワイルズの発売日とPC版(Steam版)の推薦スペックが公開されたので、おすすめのゲーミングPCをご紹介!


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です