クラス変数なるもの-2. 全てのオブジェクトで使う値、これかッ。-

なるほど、博士がプログラムなんか書けと言ったのは、「クラス変数」の使い方を実感させるためだったのか。やるなヒゲオヤジ。

クラスの中に定義して、そのクラスのオブジェクトが共通に使う変数、それが「@」が二個ついた変数「クラス変数」だったのだ。

総費用を示す変数を、クラス変数「@@total」にしよう。クラスEnemyの定義の中で、@@totalに初期値0を与えておくと、Rubyインタプリタでこの定義が読み込まれたときに、@@totalの値は0になる。

各オブジェクトの費用はインスタンス変数@costで示されるから、リスト2-1のようなメソッドtotal_costをクラスEnemyに定義してやればいい。

リスト2-1 メソッドtotal_cost

def total_cost
	@@total+=@cost
	puts "総費用:#{@@total}" 
end

トップレベルでは、たとえばリスト2-2のようにオブジェクトe1を作成したら、e1がtotal_costを呼び出す。これで、「e1の費用」が「総費用」に足しこまれる。

リスト2-2 トップレベルでメソッドtotal_costを使用する例

e1=Enemy.new("E-1", 5000)
e1.total_cost

実際は、@costの値を与えるメソッドcostと一緒にリスト2-3のように書いてもヨイ。

リスト2-3 メソッドcostを用いたメソッドtotal_cost

	def cost
		@cost
	end
	
	def total_cost
		@@total+=cost
		puts "総費用:#{@@total}" 
	end

さらに各オブジェクトの費用を報告するメソッドの中でメソッドtotal_costを呼ぶようにしちゃえば、オブジェクトはreportさえ呼び出せば自身の費用と総費用を報告できるようになる。

リスト2-4 メソッドreportの中でtotal_costも呼んじゃう

def report
	puts "#{name}作成費用:#{cost}"
	total_cost
		
end

というわけでクラス変数@@totalを使った新生プログラムreport2.rbがリスト2-5のようになる。実行結果は同じ。

リスト2-5 report2.rb

#-*- coding: shift_jis -*-

###クラスEnemyの定義###
class Enemy
	
	@@total=0 #クラス変数
	
	def initialize(name, cost)
		@name=name
		@cost=cost
		
	end

	def name
		@name
	end
	
	def cost
		@cost
	end
	
	def total_cost	#そのオブジェクトの費用を足し込む
		@@total+=cost
		puts "総費用:#{@@total}" 
	end
	
	def report
		puts "#{name}作成費用:#{cost}"
		total_cost
		
	end

end
	


###トップレベル###


e1=Enemy.new("E-1", 5000)
e1.report	#total_costも一緒に呼ばれる
e2=Enemy.new("E-2", 3000)
e2.report
e3=Enemy.new("E-DX", 8500)
e3.report

#あれ。結局繰り返しかヨ

コードは短くはなったが、やっぱりe1, e2, e3が違うってだけでおんなじこと繰り返してーんじゃーん。これナントカならないのッ!?

待てよ。繰り返しになっちゃうのは、「オブジェクトがそれぞれメソッドを呼び出さなきゃいけない」からだ。「全てのオブジェクトが共通に使う値」がクラス変数なら、「全てのオブジェクトが共通にする処理」は...フフフフフ、あったじゃないか。

 

次へ

「クラス変数なるもの」トップへ

目次へ

このページの目次へ