クラスの中で定義できるメソッドは、外から直接 呼び出せないようにアクセス制御を設定することができます。
以下から Ruby のアクセス制御で用いる「private」や「protected」の使い方を解説していきます。
目次
アクセス制御の種類
Ruby では、それぞれのメソッドに呼び出し制限を設定することができ、以下の種類があります。
public よく使う |
制限なし(デフォルトではこの設定になっている)。 |
private よく使う |
クラスの外からは呼び出せない。同じインスタンス内でのみ、関数形式で呼び出せる。 |
protected |
クラスの外からは呼び出せない。同じインスタンス内で呼び出せる。また、他のインスタンスでも同じクラスやサブクラスであれば呼び出せる。 |
以下から それぞれの使い方について、実際のプログラムを例に解説していきます。
アクセス制御の指定方法
はじめにアクセス制御の指定方法を紹介していきます。
public
、private
、protected
をクラス内で書くと、それ以降のメソッドはすべて指定した呼び出し制限が設定されます。
以下は「morning」と「evening」メソッドに private
、「night」メソッドに protected
を設定する例。
class User
def hello
p "こんにちは"
end
private
def morning
p "おはよう"
end
def evening
p "こんばんは"
end
protected
def night
p "おやすみ"
end
end
呼び出し制限の名前 :メソッド名
のようにして、アクセス制御を指定する方法もあります。
以下は「morning」と「evening」メソッドに private
を設定する例。
class User
def hello
p "こんにちは"
end
def morning
p "おはよう"
end
def evening
p "こんばんは"
end
private :morning, :evening
end
public の使い方
public を設定したメソッドは呼び出しに制限がなく、クラスの外からでも呼び出すことができます。
あらかじめ設定されているデフォルトの呼び出し制限なので、とくに明示的に指定する必要はありません。
プログラム例 その1
以下のプログラムでは、何も呼び出し制限の指定がないので「hello」メソッドは public に設定されています。
class User
def hello
p "こんにちは"
end
end
user = User.new
user.hello
"こんにちは"
public に設定されているメソッドはクラスの外からでも呼び出せるので、user.hello
で「hello」メソッドが呼び出せることが確認できます。
プログラム例 その2
以下の例では private の記述以下にある「morning」と「evening」メソッドは private
が設定されていますが、さらにその下の「night」メソッドは public にしたいので、明示的に public
を指定しています。
class User
def hello
p "こんにちは"
end
private
def morning
p "おはよう"
end
def evening
p "こんばんは"
end
public
def night
p "おやすみ"
end
end
user = User.new
user.night
"おやすみ"
「night」メソッドは public に設定してあるので、user.night
でクラスの外から「night」メソッドが呼び出せることが確認できます。
private の使い方
private を設定したメソッドはクラスの外からは呼び出せません。同じインスタンス内でのみ、関数形式で呼び出すことができます。
プログラム例 その1
以下の例では、private に設定した「morning」メソッドをクラスの外から呼び出そうとしているため、エラーとなります。
class User
private
def morning
p "おはよう"
end
end
user = User.new
user.morning
クラスの外から user.morning
で「morning」メソッドを呼び出そうとして、エラーとなります。
プログラム例 その2
今度はクラス内で「morning」メソッドを呼び出してみます。こちらはエラーになりません。
class User
def greeting
morning
end
private
def morning
p "おはよう"
end
end
user = User.new
user.greeting
"おはよう"
user.greeting
で「greeting」メソッドを呼び出し、その中で「morning」メソッドを呼び出しています。private に設定しているメソッドは同じインスタンス内で呼び出せるので、「morning」が呼び出されて「おはよう」が表示されることが確認できます。
protected の使い方
protected を設定したメソッドはクラスの外からは呼び出せません。同じインスタンス内で呼び出すことができます。また、他のインスタンスでも同じクラスやサブクラスのメソッドであれば呼び出せます。
特殊な用途になるので、使用頻度は少ないです。
プログラム例 その1
以下の例では、protected に設定した「morning」メソッドをクラスの外から呼び出そうとしているため、エラーとなります。
class User
protected
def morning
p "おはよう"
end
end
user = User.new
user.morning
クラスの外から user.morning
で「morning」メソッドを呼び出そうとして、エラーとなります。
プログラム例 その2
今度はクラス内で「morning」メソッドを呼び出してみます。こちらはエラーになりません。
class User
def greeting
morning
end
protected
def morning
p "おはよう"
end
end
user = User.new
user.greeting
"おはよう"
user.greeting
で「greeting」メソッドを呼び出し、その中で「morning」メソッドを呼び出しています。protected に設定しているメソッドは同じインスタンス内で呼び出せるので、「morning」が呼び出されて「おはよう」が表示されることが確認できます。
プログラム例 その3
protected を設定したメソッドは、以下のように他のインスタンスであっても同じクラスやサブクラスのメソッドであれば呼び出せます。
class User
def set_name(name)
@name = name
end
def become_friends(user)
p "#{get_name}さんと#{user.get_name}さんが友達になりました"
end
protected
def get_name
@name
end
end
user1 = User.new
user1.set_name("佐藤")
user2 = User.new
user2.set_name("鈴木")
user1.become_friends(user2)
"佐藤さんと鈴木さんが友達になりました"
user1.become_friends(user2)
で「become_friends」メソッドを呼び出し、その中の p "#{get_name}さんと#{user.get_name}さんが友達になりました"
のコードで「get_name」メソッドを呼び出しています。1つ目の get_name
では自身のインスタンスのメソッドを呼び出しています。2つ目の user.get_name
では引数で渡した「user2」インスタンスのメソッドを呼び出しています。
2つ目の user.get_name
では、もし「get_name」メソッドが private に設定されていた場合は、外部のメソッドのため直接呼び出すことはできませんが、今回のように protected に設定されていた場合、 「user2」インスタンスは呼び出し元と同じ「User」クラスから生成されているため、直接 呼び出すことができます。
まとめ
以上、「private」や「protected」の使い方でした!
ここまでの内容をまとめておきます。
- クラスの中で定義できるメソッドは、外から直接 呼び出せないようにアクセス制御を設定することができる。
public
、private
、protected
をクラス内で書くと、それ以降のメソッドはすべて指定した呼び出し制限が設定される。- public を設定したメソッドは呼び出しに制限がなく、どこからでも呼び出すことができる。デフォルトではこの設定になっている。
- private を設定したメソッドはクラスの外からは呼び出せない。同じインスタンス内でのみ、関数形式で呼び出すことができる。
- protected を設定したメソッドはクラスの外からは呼び出せない。同じインスタンス内で呼び出すことができる。また、他のインスタンスでも同じクラスやサブクラスのメソッドであれば呼び出せる。