かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Ruby勉強二日目

実際二日目じゃないけど、ここに記述するのは二日目ってことで!!!

クラスの定義

オブジェクト指向言語といえばクラスでしょう。
これが無きゃはじまらない!!!

定義は

class 名前
  ここに色々
end

でいける!
早速!!!

サンプル クラスの定義
# クラス作るぜ
class Hoge
	def foo
		puts "Hoge#foo"
	end
end

# クラス使うぜ
hoge = Hoge.new # インスタンス化
hoge.foo        # 定義したメソッド呼び出し
実行結果
Hoge#foo


予想通り。
インスタンス変数は、どうなってるんだろう?と思ったら@をつけたらいいらしい。
早速!!!
ついでだしコンストラクタも使うサンプルにしてしまおう。
initializeっていう名前のメソッドがコンストラクタのようだ。
引数も指定し放題?
デフォルトの値も設定できるようだ。C++みたい。

サンプル (コンストラクタ、フィールド)
# 人!
class Person
	# コンストラクタ! 引数に名前を受け取る!デフォはTarouさん
	def initialize name = "Tarou"
		@name = name # @つきがフィールド
	end
	
	# 挨拶くらいしなさいということで
	def greet
		puts "Hello!! My name is #{@name}."
	end
end

# デフォの名前
tarou = Person.new
# 明示的に名前を指定する
jirou = Person.new "Jirou"

# 後は太郎と二郎に挨拶させる
tarou.greet
jirou.greet
実行結果
Hello!! My name is Tarou.
Hello!! My name is Jirou.


無問題。
こうやって作ったフィールドって外からアクセスできるのかな?
やってみよう。
さっきのコードの後に次の文を加えて実行をしてみた。

tarou.name = "Saburou"
tarou.greet

結果は、エラー。

D:/iyan/rb140.tmp:35: undefined method `name=' for #<Person:0x2940000 @name="Tarou"> (NoMethodError)


そんなメソッドは無いか…。
じゃぁ@つければいいのか?ということでこうしてみた。

tarou.@name = "Saburou"
tarou.greet

結果は、エラー。

D:/iyan/rb140.tmp:35: parse error, unexpected tIVAR
tarou.@name = "Saburou"


文法すらあってないようだ。普通の状態じゃアクセスできないのね。
カプセル化ってやつか!!!


次。
こういうときに、外からアクセスしたいフィールドもあるよね。
そんな時の書き方が載ってた。

def なんとか=(arg)
  @なんとか = arg
end

みたいにすれば、外から代入できるみたい

def なんとか()
  return @なんとか
end

これで外から取得できるらしい。
Javaでいうところのgetter/setterってところですな。

早速!!

サンプル(getter/setter)
# 人!
class Person
	# コンストラクタ! 引数に名前を受け取る!デフォはTarouさん
	def initialize name = "Tarou"
		@name = name # @つきがフィールド
	end
	
	# 挨拶くらいしなさいということで
	def greet
		puts "Hello!! My name is #{@name}."
	end
	
	# 名前は自由にお使いください
	# getter
	def name=(name)
		@name = name
	end
	
	# setter
	def name()
		return @name
	end
end

# デフォの名前
tarou = Person.new
# 明示的に名前を指定する
jirou = Person.new "Jirou"

# 後は太郎と二郎に挨拶させる
tarou.greet
jirou.greet

# name=メソッドで名前書き換え
tarou.name = "Saburou"
tarou.greet
# nameメソッドで名前取得
puts tarou.name
実行結果
Hello!! My name is Tarou.
Hello!! My name is Jirou.
Hello!! My name is Saburou.
Saburou


名前がちゃんと書き換わってる。やりたいことが出来た。
でも、いちいち書くのめんどくさいだろ?っていうことで略記法が用意されてるらしい。

attr_accessor :名前

これでOKだとか。ラクチン。
さっきのPersonクラスをこれを使って書き換えると

# 人!
class Person
	# コンストラクタ! 引数に名前を受け取る!デフォはTarouさん
	def initialize name = "Tarou"
		@name = name # @つきがフィールド
	end
	
	# 挨拶くらいしなさいということで
	def greet
		puts "Hello!! My name is #{@name}."
	end
	
	# 名前は自由にお使いください
	# getter
	# def name=(name)
	# 	@name = name
	# end
	# setter
	#def name()
	#	return @name
	#end
	attr_accessor :name
end


スッキリ。
読み取り専用、書き込み専用の略記法もある。

読み取り専用 attr_reader :hoge
書き込み専用 attr_writer :hoge
両方 attr_accessor :hoge


用途に応じて使い分けてください。

継承

ついに継承。
といってもそんなに書くことは無い。
継承の仕方は

class クラス名 < 親クラス名
end

以上!!


簡単なサンプルだけでお茶をにごす。

サンプル(継承)
# 本当に普通の人なんです。
class Man
    attr_accessor :name
    
    def initialize name = "Tarou"
        @name = name
    end
    
    # 挨拶は大事
    def greet
        puts "こんにちは。私の名前は#{@name}です。"
    end
    
    # 謙虚さも大事
    def talk
        puts "私は普通の人ですよ."
    end
end

# あの人なんです。でも所詮普通の人が元なんです。
class SuperMan < Man
    # でも、しゃべることは凄いんです。
    def talk
        puts "私は凄い人ですよ."
    end
end

# 普通の人お願い!
man = Man.new
man.greet
man.talk

# スーパーマンお願い!
super_man = SuperMan.new
super_man.greet
super_man.talk
実行結果
こんにちは。私の名前はTarouです。
私は普通の人ですよ.
こんにちは。私の名前はTarouです。
私は凄い人ですよ.


同じTarouさんとは思えないくらい自信満々になっちゃいました。
継承することで、自信の無い部分を自信満々に置き換えちゃったんですね。


今日はここまで!!
次は正規表現かな〜?