クラス定義でメソッドへのアクセス制限・public, private, protected
お金 | 仕事 | 勉強 | プライベート | 健康 | 心
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般
Rubyのクラス定義においては、C++やPHPと同じように、public, private, protectedキーワードにより、メソッドへののアクセス制限を設定できます。
考え方は、C++やPHPと似たような感じですので、以下をご参考お願いします。
参考:
C++のクラス定義でのアクセス制限
PHPのクラス定義でのアクセス制限
Rubyの場合、C++やPHPと違うのは、インスタンス変数・クラス変数を直接に参照・変更はできず、アクセスメソッドを通して行います。
したがって、アクセス制限は、メソッドのみが対象となります。
クラス内部でしか利用すべきでないメソッドは、privateやprotectedにしておきます。
また、アクセス制限の宣言を何も行わない場合、デフォルトではpublicとなります。
public, private, protectedの実験
簡単なテストを行ってみました。
以下のようなスーパークラスとサブクラスを書く。
class AccessTest
public
def pub
puts "public_method"
end
protected
def pro
puts "protected_method"
end
private
def priv
puts "private_method"
end
end
class SubAccessTest < AccessTest
def pub_s
pub
end
def pro_s
pro
end
def priv_s
priv
end
end
で、まずはスーパークラスのインスタンスを生成して実験。
test_super = AccessTest.new test_super.pub test_super.pro # エラー est_super.priv # エラー
出力結果。
public_method
スーパークラスのインスタンス化では、protectedとprivateは、エラーとなり予想通りの実行結果です。
次に、サブクラスのインスタンスで実験。
test_sub = SubAccessTest.new test_sub.pub_s test_sub.pro_s test_sub.priv_s
実行結果。
public_method protected_method private_method
ゲゲゲーッ。
予想を裏切って、”private_method”まで出力しちゃってます。
この動作は、C++やPHPと違う・・・。
Rubyの場合、private宣言したメソッドでも、継承したサブクラスのインスタンスからアクセス可能となっています。
こうなると、privateとprotectedの違いが気になります。
protectedの場合、クラスの内部(定義クラスとサブクラス)からはインスタンスメソッドとして呼び出せる、という記述があったので、以下のテストを行ってみました。
protectedのテスト
class TestPro
protected
def pro
puts "protected_method"
end
public
def pro_p
TestPro.new.pro
end
end
class SubTestPro < TestPro
def pro_s
TestPro.new.pro
end
end
TestPro.new.pro_p
SubTestPro.new.pro_s
実行結果。
protected_method protected_method
なるほど・・・サブクラスも含めて、クラス内部からであれば、インスタンスメソッドとして使え、インスタンスから呼び出しできます。
privateのテスト
class TestPriv
private
def priv
puts "private_method"
end
public
def priv_p
TestPriv.new.priv
end
end
class SubTestPriv < TestPriv
def priv_s
TestPriv.new.priv
end
end
TestPriv.new.priv_p # エラー
SubTestPriv.new.priv_s # エラー
privateの場合、クラスおよびそのサブクラス内から、インスタンスメソッドとしては呼び出すことができません。
protectedとprivateの違いは確認できましたが、ちょっと今のところ使いどころは分かりません。
以下に、まとめておきます。
public
そのメソッドが定義されたクラス内、サブクラス、クラス外(インスタンス)のどこからでもアクセス可能です。
private
メソッドは、クラスの内部(定義クラスとサブクラス)からのみアクセス可能。
レシーバを指定して呼び出すのは不可で、クラス内部からでもインスタンスメソッドとしては使えない。
protected
メソッドは、クラスの内部(定義クラスとサブクラス)からのみアクセス可能。
レシーバを指定して呼び出すことができ、クラス内部からであればインスタンスメソッドとして使える。
Rubyのアクセス制限キーワードは、C++やPHPよりちょっと分かりにくいです。
- - 関連記事 -
- 特異クラスによるクラスメソッド定義・class << self ~ end
- モジュールの使い方
- クラス継承
- クラス拡張
- クラス変数・クラスメソッド
- アクセスメソッド(アクセサ)をattr_reader, attr_writer, attr_accessorで定義
- アクセスメソッド(アクセサ)
- Rubyのクラス定義・initialize(コンストラクタ)
- スーパークラスとサブクラス・クラス継承
- classメソッド・オブジェクトが属するクラスを調べる
- private, protected アクセス指定の違い
- オブジェクトのコピーを作る
- Rubyのinitializeメソッドの継承