クラス定義でメソッドへのアクセス制限・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メソッドの継承