【Ruby】クラスの定義・作成方法まとめ|インスタンス変数・initialize、継承などを実例でわかりやすく解説

ruby-prograshi(プロぐらし)-kv ruby
記事内に広告が含まれていることがあります。

Rubyでクラスを定義する方法について、インスタンス変数の定義方法、インスタンスの生成、インスタンスメソッドの使い方、ファイルを分割する方法など、基本的なコーディング方法を実例を交えてまとめています。


クラス定義

class クラス名

end

 └ クラス名は冒頭大文字
 └ 1行目文末に「:」不要
 └ 文末に「end」必須


インスタンス変数の定義(attr_accessor :)

インスタンス毎に固有となる値を格納する変数。

attr_accessor :インスタンス変数名 
 └ attr_accessorの直後はスペース
 └ スペースの後ろにシンボル(:値)
 └ 「:」と「値」の間はスペースなし

class Product
  attr_accessor :name
  attr_accessor :price
end

インスタンス変数「name」と「price」を定義。


インスタンスの生成(.new)

クラス名.new

class Product
  attr_accessor :name
  attr_accessor :price
end

#インスタンス生成
product1 = Product.new


インスタンス変数に値を入れる

インスタンス名.インスタンス変数名 = 値

class Product
  attr_accessor :name
  attr_accessor :price
end

#インスタンス生成
product1 = Product.new

#インスタンス変数に値をセット
product1.name = "iphone"
product1.price = 100000


puts product1.name
puts product1.price

#出力
iphone
100000

上記例では、product1というインスタンスの、nameにiphoneをセット、priceに100000をセットしています。


インスタンスメソッド(クラス内で定義したメソッド)

クラス内のメソッドをインスタンスメソッドと呼びます。

class クラス名
  def メソッド名(引数名)
    処理
  end
end

※クラスにもメソッドにもそれぞれendが必要です。

インスタンスメソッドの呼び出し

インスタンス名.メソッド名

インスタンス変数を呼び出すのと同じです。

class Product
  attr_accessor :name
  attr_accessor :price

  def create
    return "インスタンスを生成しました(return)"
  end
end

#インスタンス生成
product1 = Product.new

#インスタンスメソッド呼び出し
puts product1.create


#出力
インスタンスを生成しました(return)


インスタンスメソッドの中でインスタンス変数を使う

self.インスタンス変数名

class Product
  attr_accessor :name
  attr_accessor :price

  def create
    puts "製品名は#{self.name}です"
    puts "価格は#{self.price}です"
  end
end

#インスタンス生成
product1 = Product.new

#インスタンス変数に値をセット
product1.name = "iphone"
product1.price = 100000

#インスタンスメソッド実行
product1.create


#出力
製品名はiphoneです
価格は100000です

※インスタンスメソッド内のputsをreturnにした場合は、呼び出すメソッドの前にputsをつける。(puts product1.create)


インスタンスメソッドの中でif文を使う

class Product
  attr_accessor :name
  attr_accessor :price

  #注文数10個以上で10%OFFするメソッド
  def get_total_price(count)
    total_price = self.price * count
    if count >=10
      total_price *= 0.9
    end
    return total_price
  end
end

#インスタンス生成
product1 = Product.new

#インスタンス変数に値をセット
product1.name = "iphone"
product1.price = 100000

#インスタンスメソッド実行
puts product1.get_total_price(10)

#出力
900000


initializeメソッド

インスタンス生成時に自動で実行される関数です。

インスタンス生成時に引数を渡し、インスタンス変数をセットします。

class クラス名
  def initialize(引数名)
    処理
  end
end

#インスタンス生成
インスタンス名 = クラス名.new(引数)

▼initializeメソッドでインスタンス変数をセット

class Product
  attr_accessor :name
  attr_accessor :price

 def initialize(name,price)
    self.name = name
    self.price = price
 end

 def info
   return "製品名:#{self.name}、価格:#{self.price}"
 end

end

#インスタンス生成
product1 = Product.new("iphone", 100000)

puts product1.info

#出力
製品名:iphone、価格:100000

▼キーワード引数を使う

class Product
  attr_accessor :name
  attr_accessor :price

 def initialize(name:,price:)
    self.name = name
    self.price = price
 end

 def info
   return "製品名:#{self.name}、価格:#{self.price}"
 end
end

#インスタンス生成
product1 = Product.new(name:"iphone", price:100000)

puts product1.info


#出力
製品名:iphone、価格:100000


ファイル分割(require “”)

require "./ファイル名"
 └ 拡張子「.rb」は不要

▼クラス定義を書いた「product.rb」を「index.rb」冒頭で読み込む。

class Product
  attr_accessor :name
  attr_accessor :price

 def initialize(name:,price:)
    self.name = name
    self.price = price
 end

 def info
   return "製品名:#{self.name}、価格:#{self.price}"
 end
end
#ファイル読み込み
require "./product"

#読み込んだファイルのクラスでインスタンス生成
product1 = Product.new(name:"iphone", price:100000)
puts product1.info

#出力
製品名:iphone、価格:100000


複数のインスタンスをeachメソッドで個々に抜き出す

以下手順で、複数のインスタンスをeachメソッドで個々に抜き出す例です。

処理内容
  • クラス定義とインスタンス生成をファイル分割。
  • インスタンスを複数生成し、配列に格納。
  • eachメソッドでインスタンスを一つづつ呼び出す。
  • 各インスタンスでinfoメソッドを実行。
class Product
  attr_accessor :name
  attr_accessor :price

 def initialize(name:,price:)
    self.name = name
    self.price = price
 end

 def info
   return "製品名:#{self.name}、価格:#{self.price}"
 end
end
#ファイル読み込み
require "./product"

#読み込んだファイルのクラスでインスタンス生成
product1 = Product.new(name:"iphone6s", price:60000)
product2 = Product.new(name:"iphone8", price:80000)
product3 = Product.new(name:"iphoneX", price:100000)
product4 = Product.new(name:"iphone11pro", price:120000)

#インスタンスを配列に格納
products = [product1,product2, product3, product4]

#eachメソッドでインスタンスを一つづつ取り出す
products.each do |product|
  #各インスタンスでinfoメソッドを実行
  puts product.info


#出力
製品名:iphone6s、価格:60000
製品名:iphone8、価格:80000
製品名:iphoneX、価格:100000
製品名:iphone11Pro、価格:120000


インデックス番号をつける

eachメソッドで要素を抜き出すときに、各要素にインデックス番号を付与することができます。

  • eachメソッドと1づつ増加する変数を組み合わせる。
  • 変数展開で、index番号とinfoメソッドを出力する。
#ファイル読み込み
require "./product"

#読み込んだファイルのクラスでインスタンス生成
product1 = Product.new(name:"iphone6s", price:60000)
product2 = Product.new(name:"iphone8", price:80000)
product3 = Product.new(name:"iphoneX", price:100000)
product4 = Product.new(name:"iphone11pro", price:120000)

#インスタンスを配列に格納
products = [product1,product2, product3, product4]

#インデックス番号用の変数を定義
index = 0

#eachメソッドでインスタンスを一つづつ取り出す
products.each do |product|
  #各インスタンスでinfoメソッドを実行
  puts "#{index}. #{product.info}"
  index += 1

#出力
0. 製品名:iphone6s、価格:60000
1. 製品名:iphone8、価格:80000
2. 製品名:iphoneX、価格:100000
3. 製品名:iphone11Pro、価格:120000


入力値の受け取り(gets.chomp)

変数名 = gets.chomp

enterキーが押されるまでに入力された内容を変数に格納する。※文字列として格納

文字列を数値に変換(.to_i)

gets.chompで受け取った情報は文字列のため、数値に変換する。
変数名 = gets.chomp.to_i

puts "ニックネームを入力してください"
name = gets.chomp.to_i

puts "年齢を入力してください"
age = gets.chomp.to_i

future_age = age+30

puts "#{name}さんの30年後の年齢は#{future_age}です"


入力値の受け取りとインスタンス

インスタンスのインデックス番号と注文個数を受け取る。

  • 受け取った入力値に該当するインスタンスを選択。
  • 注文個数を受け取り合計金額を返す。

▼クラス定義したファイル

class Product
  attr_accessor :name
  attr_accessor :price

 def initialize(name:,price:)
    self.name = name
    self.price = price
 end

 def info
   return "製品名:#{self.name}、価格:#{self.price}"
 end
end
#ファイル読み込み
require "./product"

#読み込んだファイルのクラスでインスタンス生成
product1 = Product.new(name:"iphone6s", price:60000)
product2 = Product.new(name:"iphone8", price:80000)
product3 = Product.new(name:"iphoneX", price:100000)
product4 = Product.new(name:"iphone11pro", price:120000)

#インスタンスを配列に格納
products = [product1,product2, product3, product4]

#インデックス番号用の変数を定義
index = 0

#eachメソッドでインスタンスを一つづつ取り出す
products.each do |product|
  #各インスタンスでinfoメソッドを実行
  puts "#{index}. #{product.info}"
  index += 1

#商品番号の受け取り
puts "商品番号を入力してください"
order = gets.chomp.to_i

selected_product = products[order]

#注文数の受け取り
puts "選択した製品は#{selected_product.name}です"
puts "何個注文しますか?"
count = gets.chomp.to_i

#合計金額の算出
total_price = selected_product.price * gets.chomp.to_i * 1.1

puts "合計金額は#{total_price}です"


継承(<)

親クラスのインスタンス変数とインスタンスメソッドを引き継ぐ。

class 子クラス名 < 親クラス名
 └ 冒頭は大文字
 └ 最後にend必須
 └ 親クラスが上にある(or 別ファイルで読み込み済み)

require "./親クラスのファイル名"

class 子クラス名 < 親クラス名

end 

継承のファイル分割

ファイルは大きく4つに分類される。
カッコはファイル名の例。

  • 親クラスを定義したファイル (親クラス名.py)
  • 子クラスを定義したファイル(子クラス名.py)
  • インスタンス生成用のファイル(data.py)
  • 出力用ファイル(index.py)

子クラスを定義したファイルは、子クラス毎に作成。
(コード量によって、1ファイルにまとめたり)

インスタンス変数の追加

シンプルに継承したクラスの中で新たにインスタンス変数を定義するだけ。

attr_accessor :インスタンス変数名

class Product
  attr_accessor :name
  attr_accessor :price

 def initialize(name:,price:)
    self.name = name
    self.price = price
 end

 def info
   return "製品名:#{self.name}、価格:#{self.price}"
 end
end

▼継承でPhoneクラスを作成。
インスタンス変数weightを追加。

require "./product"

class Phone < Product
   attr_accessor :weight
end

▼子クラスPhoneで生成したインスタンスに値をセット

require "./phone"

#インスタンス生成
phone1 = Phone.new(name: "iphone11", price: "120000")

#追加したインスタンス変数に値をセット
phone1.weight = "194g"

puts phone1.weight

#出力
194g

インスタンスメソッドの追加

シンプルに継承したクラスの中で新たにインスタンスメソッドを定義するだけ。

▼上記phone.rbにメソッドを追加。
self.インスタンス名
 └ クラス内でのインスタンス変数の呼び出し

require "./product"

class Phone < Product
   attr_accessor :weight

   def set_property
      return "#{self.name}の重さは#{self.weight}です"
   end     
end

▼追加メソッドの呼び出し

require "./phone"

#インスタンス生成
phone1 = Phone.new(name: "iphone11", price: "120000")

#追加したインスタンス変数に値をセット
phone1.weight = "194g"

#追加したメソッドの呼び出し
puts phone1.set_property

#出力
iphone11の重さは194gです

オーバーライド

インスタンス変数・メソッドの上書きのこと。
(親クラスで既に定義されているものならオーバーライドになる)

class Product
  attr_accessor :name
  attr_accessor :price

 def initialize(name:,price:)
    self.name = name
    self.price = price
 end

 def info
   return "製品名:#{self.name}、価格:#{self.price}"
 end
end

▼親クラスのinfoメソッドをオーバーライド

require "./product"

class Phone < Product
   attr_accessor :weight

   #オーバーライド
   def info
      return "製品名:#{self.name}、価格:#{self.price}円、重さ:#{self.weight}"
   end     
end

▼オーバーライドしたメソッドの呼び出し

require "./phone"

#インスタンス生成
phone1 = Phone.new(name: "iphone11", price: "120000")

#追加したインスタンス変数に値をセット
phone1.weight = "194g"

#追加したメソッドの呼び出し
puts phone1.info

#出力
製品名:iphone11、価格:120000円、重さ:194g

親クラスで重複するメソッドの呼び出し(super)

initializeで既に定義済みのメソッドを呼び出す。
super(引数:親クラスの変数)

▼親クラス

class Product
  attr_accessor :name
  attr_accessor :price

#オーバーライドで呼び出す箇所
 def initialize(name:,price:)
    self.name = name
    self.price = price
 end

 def info
   return "製品名:#{self.name}、価格:#{self.price}"
 end
end
require "./product"

class Phone < Product
   attr_accessor :weight

   #initializeのオーバーライド(既存部呼び出し)
   def initialize(name:, price:, weight:)
      super(name: name, price: price)      
      self.weight = weight
   end

   #オーバーライド
   def info
      return "製品名:#{self.name}、価格:#{self.price}円、重さ:#{self.weight}"
   end     
end


デフォルトで用意されているクラスの読み込み

require "クラス名"
 └ ファイルの読み込みとは異なる
  (require “./ファイル名”)


Dateクラス

デフォルトでRubyに定義されているクラスの一つ。
▼クラスの読み込み
require "date"

▼Dateインスタンスの生成
変数 = Date.new(yyyy, m, d)

▼出力
yyyy-mm-dd

require "date"

yesterday = Date.new(2020, 5, 30)
puts yesterday

#出力
2020-05-30


Dateクラスのインスタンスメソッド

指定曜日か確認する

指定した曜日か確認 → 真偽値で返す。
インスタンス名.曜日?

require "date"

yesterday = Date.new(2020, 5, 30)
puts yesterday.monday?
puts yesterday.saturday?

#出力
false
True


Dateクラスのクラスメソッド

今日の日付を確認する(.today)

Date.today

require "date"

date1 = Date.today
puts date1

#出力
2020-05-31


インスタンスメソッドとクラスメソッド

  • インスタンスメソッド
    • インスタンスに対し呼び出す
    • インスタンス名.メソッド名
    • 定義:def メソッド名
    • 文末にend
  • クラスメソッド
    • クラスに対して呼び出す
    • クラス名.メソッド名
    • 定義:def クラス名.メソッド名
    • 文末にend

クラスメソッドを用いるとき
・インスタンスによらない結果を出力する。

例:今日の日付を求める。
Date.today


クラスメソッドの作成と呼び出し

クラスメソッドは自分で作れる。
def クラス名.メソッド名

▼今日の日付が月曜日か調べるクラスメソッド

  • Dateクラスを読み込む
  • クラスメソッドを定義する
require "date"

class Product
  attr_accessor :name
  attr_accessor :price

 def initialize(name:,price:)
    self.name = name
    self.price = price
 end

 def info
   return "製品名:#{self.name}、価格:#{self.price}"
 end

#クラスメソッドを定義
 def Product.is_today_off
   today = Date.today
   if today.monday
     "今日は定休日です" 
   else
     self.info
end

▼定義したクラスメソッドを使う

require "./product"

product1 = Product.new(name: "iphone11", price: "120000")

#クラスメソッドの呼び出し
Product.is_today_off

タイトルとURLをコピーしました