はじめに
クラスについて勉強したことをまとめました!
参考
プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで
クラスの定義方法
class クラス名
end
で定義します。クラス名は、キャメルケースで書くのが一般的です。
class User
end
オブジェクトの生成方法
クラス名.newで生成します。
User.new
initializeメソッド
newメソッドでがオブジェクト生成されると、initializeメソッドが自動的に呼び出されます。
初期化を行いたい場合は、initializeメソッド内に処理を記述します。
class User
def initialize
puts "hello"
end
end
#initializeメソッドが呼び出されるため、"hello"が出力される
User.new #=>hello
initializeメソッドは、外部から呼び出すことはできません。
class User
def initialize
puts "hello"
end
end
taro = User.new #=>hello
taro.initialize #=>NoMethodError
initializeメソッドに引数をつける際は、newメソッドにも引数を付与する必要があります。
class User
def initialize(name,age)
puts "私は#{name}。#{age}歳"
end
end
taro = User.new('太郎',15) #=>私は太郎。15歳
taro = User.new #=>ArgumentError
インスタンスメソッド
クラス内で定義したメソッドのことをインスタンスメソッドといいます。
インスタンスメソッドは、オブジェクトから呼び出すことが可能です。
class User
#これがインスタンスメソッド
def greeting
puts "私は太郎。15歳"
end
end
user = User.new
#インスタンスメソッドは、生成したオブジェクトから呼び出せる
user.greeting #=>私は太郎。15歳
インスタンス変数
インスタンス変数とは、生成されたオブジェクト内で共有される変数のことです。
下記のように、変数名の@を付けると、インスタンス変数になります。
class User
def initialize(name)
#これがインスタンス変数
@name = name
end
def greeting
#インスタンス変数はインスタンスメソッドで使用できる
puts "私は#{@name}"
end
end
taro = User.new('太郎')
taro.greeting #=>私は太郎
インスタンス変数をクラスの外から参照・変更する
attr_accessorメソッドを使用すると、クラスの外からインスタンス変数を参照したり、書き換えることができます。
class User
#@nameが自動的に外から読み書きできるようになる。
attr_accessor :name
def initialize(name)
@name = name
end
end
user = User.new('太郎')
#インスタンス変数を外から参照することができる
puts user.name #=> 太郎
#インスタンス変数を外から書き換えることができる
user.name = '佐藤'
puts user.name #=> 次郎
インスタンス変数をクラスの外から参照のみ行う
インスタンス変数をクラスの外から参照のみ行う場合は、attr_readerメソッドを使用します。
class User
#インスタンス変数の読み取りが可能になる
attr_reader :name
def initialize(name)
@name = name
end
end
user = User.new('太郎')
#インスタンス変数を外から参照することができる
puts user.name #=> 太郎
#インスタンス変数を外から書き換えはできない
user.name = '佐藤' #=>NoMethodError
インスタンス変数をクラスの外から変更のみ行う
インスタンス変数をクラスの外から変更のみ行う場合は、attr_writerメソッドを使用します。
class User
# インスタンス変数の書き込みが可能になる
attr_writer :name
def initialize(name)
@name = name
end
end
user = User.new('太郎')
#インスタンス変数を外から書き換えは可能
user.name = '佐藤'
#参照はできない
puts user.name #=>NoMethodError
ローカル変数
クラスにて、メソッドやブロック内で生成される変数のことをローカル変数と呼びます。
ローカル変数は、そのメソッドやブロック内でのみ有効で、呼び出される度に作り直されます。
ローカル変数は、アルファベットの小文字、_で始めます。
class User
def initialize(name)
@name = name
end
def greeting
#これがローカル変数
age = 15
#ローカル変数は、そのメソッドやブロック内で使用できる
puts "私は#{@name}。#{age}歳"
end
end
taro = User.new('太郎')
taro.greeting #=>私は太郎。15歳
# 外からは参照できない
taro.age #=>私は太郎。15歳
クラスメソッドの定義
メソッド名の頭にself.を付けるとクラスメソッドを定義できます。
class User
#メソッド名の頭にselfを付けるとクラスメソッドになる
def self.クラスメソッド
end
#クラスメソッドが複数になる場合は、下記のようにも書ける
class << self
def クラスメソッド1
end
def クラスメソッド2
end
end
end
定数
クラス内には、定数も定義することが可能です。
定数は慣習的に、アルファベットの大文字で定義されます。
定数は、インスタンスメソッド・クラスメソッドともに参照可能です。
class Product
#定数の生成
DEFAULT_PRICE = 100
def self.default_price
#クラスメソッド内で定数を参照
DEFAULT_PRICE
end
def default_price
#インスタンスメソッド内で定数を参照
DEFAULT_PRICE
end
end
product = Product.new
# インスタンスメソッドから参照可能
puts product.default_price #=>100
# クラスメソッドから参照可能
puts Product.default_price #=>100
self
selfとは、インスタンスそのものを表すキーワードです。
class User
attr_reader :name
def initialize(name)
@name = name
end
#self無しでnameを呼び出す場合
def hello
puts "こんにちは!#{name}"
end
#selfありでnameを呼び出す場合
def hi
puts "こんにちは!#{self.name}"
end
#インスタンス変数を直接呼び出す場合
def my_name
puts "こんにちは!#{@name}"
end
end
user = User.new('太郎')
user.hello #=>こんにちは!太郎
user.hi #=>こんにちは!太郎
user.my_name #=>こんにちは!太郎
メソッド内でセッターメソッドを呼び出す際の注意点
下記のように、セッターメソッド経由でインスタンス変数を書き換える際、selfを付けないと、ローカル変数として認識され、意図しない動作を出力しますので、注意が必要です!
class User
# セッターメソッドnameを設定
attr_accessor :name
def initialize(name)
@name = name
end
# セッターメソッドのnameを書き換えたい(正解)
def rename1(name)
self.name = name
end
# セッターメソッドのnameを書き換えたい(間違い)
def rename2(name)
name = name
end
end
user = User.new('太郎')
# rename前のため、"太郎"が表示される
puts user.name #=>"太郎"
user.rename1('佐藤')
# インスタンス変数のnameが書き換わる
puts user.name #=>"佐藤"
# ローカル変数のnameに’田中’が代入されたため、user.nameは変わらない
user.rename2('田中')
puts user.name #=>"佐藤"
クラス直下のself
クラスの直下やクラスメソッド内にselfを使用すると、クラスを返します。
class User
# クラス直下のselfは、クラスになる
puts self #=> User
#クラスメソッドでselfを返す
def self.return
self
end
# インスタンスメソッドでselfを返す
def return
self
end
end
# selfはクラスになる
puts User.return #=>User
user = User.new
# selfはインスタンスになる
puts user.return #=>#<User:0x00007ffb591b2360>
承継
「aはbの一種である」という関係が成り立つものを承継といいます。
例:「家電は商品の一種である」といった具合。
この時、家電のことをサブクラス。商品をスーパークラスと呼びます。
クラスを確認する方法
- classメソッド
- instance_of?メソッド
の二つがあります。
class User
end
user = User.new
puts user.class #=> User
#userはUserクラスであるためtrueを返す
puts user.instance_of?(User) #=> true
#userはUserクラスでないためfalseを返す
puts 'text'.instance_of?(User) #=> false
承継関係であるか調べる方法
is_a?メソッドを使用します。
class User
end
user = User.new
# 承継関係にあるためtrueを返す
puts user.is_a?(Object) #=> true
puts user.is_a?(BasicObject) #=> true
# 承継関係でないためfalseを返す
puts user.is_a?(String) #=> false
子で親クラスのメソッドを呼び出す方法
superメソッドを使います。
class Product
attr_accessor :name, :price
def initialize(name,price)
@name,price = name,price
end
end
class DVD < Product
def initialize(name,price,running_time)
#superメソッドで、親クラスのメソッドを呼び出せる
@running_time = running_time
end
end
dvd = DVD.new('トイストーリー',2000,2)
#子で定義していないメソッドを呼び出せる
puts dvd.name #=> トイストーリー
メソッドの公開レベル
メソッドがどこからどこまでの範囲で使用できるかについて、主に三種類あります。
publicメソッド
クラスの外から使用できるメソッド
インスタンスメソッドはクラスの外からでも使用できるため、publicメソッドに相当します。
class User
#インスタンスメソッドを定義
def hello
puts "hello"
end
end
user = User.new
#クラスの外からでも呼び出せるため、publicメソッドに相当
user.hello
privateメソッド
privateメソッドとは、クラス内で使用できるメソッドのこと。クラスの外からは呼び出すことができません。
privateキーワード以降に定義したメソッドは、privateメソッドになります。
class User
private
#privateキーワード以降にメソッドを定義
def hello
puts "hello"
end
end
user = User.new
# privateメソッドを呼び出したため、エラーとなる
user.hello #=> private method `hello' called for #<User:0x00007fb74413e400> (NoMethodError)
スーパークラスで定義されたprivateメソッドですが、サブクラスで呼び出すことができるので注意が必要です。
class Product
private
def price
1000
end
end
class DVD < Product
def tax_price
# スーパークラスのprivateメソッドを呼び出す
price * 1.1
end
end
dvd = DVD.new
# サブクラスでスーパークラスのprivateメソッドを呼び出しても、エラーにならない
puts dvd.tax_price #=>1100.0
また、クラスメソッドをprivateメソッドとしたい場合は,class << self構文を使用する必要があります。
class Product
private
def self.price
1000
end
end
# 上記の記述では、プライベートメソッドにしたつもりのpriceが外から呼び出せてしまう
puts Product.price #=>1000
class Product
# class << self構文
class << self
private
#クラスを定義
def price
1000
end
end
end
#クラスメソッドが外から呼び出せない(privateメソッドとして機能している)
puts Product.price #=> NoMethodError
定数
定数はメソッド内では定義できない
定数は、メソッド内では作成できず、クラス直下に定義する必要があります。
class Product
def price
# メソッド内で定数を作成すると構文エラーになる
PRICE = 1000
end
end
product = Product.new
puts product.price
#=>dynamic constant assignment