クラス定義でメソッドへのアクセス制限・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よりちょっと分かりにくいです。

スポンサーリンク
 
スポンサーリンク