クラス変数・クラスメソッド
お金 | 仕事 | 勉強 | プライベート | 健康 | 心
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般
Rubyのクラス変数・クラスメソッドとは、CやPHPでの静的プロパティ・静的メソッドと同様のものです。
インスタンス(オブジェクト)に対する操作ではなくて、クラスそのものに対する操作を行うメソッドとなります。
インスタンスを生成する利点は、インスタンスに固有のデータを扱うことができる点です。
しかし、データによっては、インスタンスに固有ではなく、すべてのインスタンスで共通して使うようなデータもあります。
共有して使うものに関しては、クラス変数やクラスメソッドを定義します。
クラス変数
クラス変数は、他言語では、静的プロパティ、静的メンバ変数、スタティック変数などとも呼びます。
クラスメソッドは、静的メソッド、静的メンバ関数、スタティックメソッドなどとも呼びます。
CやPHPの場合ですと、staticキーワードで宣言しますね。
以下、クラス変数とクラスメソッドを用いた例です。
プロフィールを作成した人数(Profileクラスから生成したインスタンスの数)を求めるために、クラス変数とクラスメソッドを用いています。
プロフィールの人数は、どのインスタンスからも共有すべき情報ですので、データがクラスに属するようにします。
クラス変数とクラスメソッドの定義の書き方
class Profile @@count = 0 # 人数 def initialize(name_one) @name = name_one @@count += 1 # プロフィールが作成されるたびに人数をカウントアップ end # 人数を取得するクラスメソッド def Profile.count return @@count end # 名前の参照と変更 attr_accessor :name end # Tommyのプロフィール作成(1人目) tom = Profile.new("Tommy") puts tom.name # Williamのプロフィール作成(2人目) wil = Profile.new("Wiliam") puts wil.name # 綴り間違い。Williamに訂正する wil.name = "William" puts "collect: #{wil.name}" # Saekoのプロフィール作成(3人目) saeko = Profile.new("Saeko") puts saeko.name puts "total: #{Profile.count} people" # ここまでの人数確認 # Hirosiのプロフィール作成(4人目) hirosi = Profile.new("Hirosi") puts hirosi.name puts "total: #{Profile::count} people" # ここまでの人数確認
実行結果
Tommy Wiliam collect: William Saeko total: 3 people Hirosi total: 4 people
インスタンスが生成されるたびに(initializeで初期化が行われるたびに)、人数(@@countで表すクラス変数)を、カウントアップしています。
また、人数を参照するのは、どのインスタンスからも共通の機能になりますから、人数を取得するクラスメソッドを、「Profile.count」というクラスメソッドで定義しています。(Profile.count()と括弧をつけても良い)
ほかのクラスメソッド定義の書き方
また、クラスメソッドの定義の仕方は、
class Profile ・・・ def Profile.count return @@count end end
のほかにも、
class Profile ・・・ def self.count return @@count end end
という書き方もできます。
selfを用いれば、クラス名を、クラスメソッド定義で直に書くことを避けれます。
特異クラスを使ったクラスメソッド定義
また、特異クラスを使ったクラスメソッドの定義の書き方も可能です。
ただし、@@countをreturnしようとしたら、NameErrorが出ました。
@@countクラス変数を使わず、特定の文字列を出力するクラスメソッド(クラスの特異メソッド)であれば、実行できました。
class Profile ・・・ end class << Profile def count put "hello" # return @@count #=> これはNameErrorとなった。 #warning: class variable access from toplevel singleton method #NameError: uninitialized class variable @@count in Object end end
というふうにクラスメソッドを定義できます。
「class << Profile」という書き方は、特異クラスと呼ばれます。
Rubyでは、Profileというクラス自体もオブジェクト(Classクラスのインスタンス)であり、上のように特異クラスのなかで特異メソッドを定義する書き方も可能です。
Profileクラスというオブジェクトの特異メソッド、countを定義するという意味で、すなわち、クラスメソッドとはクラスの特異メソッドと同義。
特異メソッド、特異クラスに関しては、もう少ししっかり勉強する。
「def Profile.count」、または「def self.count」の書き方が簡単だと思います。
「def Profile.count」というクラスメソッドの書き方ですと、クラス名が変更したときに、クラスメソッドの部分の変更も必要となります。
ただ、クラス名が付いていることで、直感的にクラスメソッドであることが分かりやすいというメリットもありますので、必要に応じて、「クラス名.メソッド名」と「self.メソッド名」の2種類の書き方を使い分けると良いかもです。
あと、クラスメソッドを利用する際には、「Profile.count」のほか「Profile::count」という書き方も可能です。
PHPに慣れてるとこっちの書き方に馴染みがありますね。
- - 関連記事 -
- 特異クラスによるクラスメソッド定義・class << self ~ end
- モジュールの使い方
- クラス定義でメソッドへのアクセス制限・public, private, protected
- クラス継承
- クラス拡張
- アクセスメソッド(アクセサ)をattr_reader, attr_writer, attr_accessorで定義
- アクセスメソッド(アクセサ)
- Rubyのクラス定義・initialize(コンストラクタ)
- スーパークラスとサブクラス・クラス継承
- classメソッド・オブジェクトが属するクラスを調べる
- private, protected アクセス指定の違い
- オブジェクトのコピーを作る
- Rubyのinitializeメソッドの継承