第 4 第 Ruby 第第第 第第 第第 :
Jun 28, 2015
第 4回 Ruby研究会担当:石河
AGENDA
オブジェクト指向機能 ポリモルフィズム
ダックタイピング 動的型
継承 Mix-in
include extend
ポリモルフィズム
多態性 同じ名前のメソッドが、レシーバのオブジェクトによって違う動きをする
開け方の違う箱が3つあるとして、箱を開けたい時は開けろと命令するだけで蓋を持ちあげる 紐を解く 鍵をあける
それぞれに適した方法であけてくれるというイメージです (まつもとさん曰く )
sizeメソッドはオブジェクトの大きさを求めるメソッド
String#size 文字列の大きさを返す
Array#size 要素の数を返す
【コード】 a = "A" p a.size
a = 12 p a.size
a= [1,2,3] p a.size
a= [1.2],[3,4] p a.size
【出力】 1 4 3 2
整数の実装上のサイズをバイト数で返します
ダックタイピング
"If it walks like a duck and quacks like a duck, it must be a duck“
(もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである)
オブジェクトのクラスによらず、そのオブジェクトが期待通りに振る舞えば適切なものとして扱う
【コード】 def add_values(*v) return v.inject{|
result,item| result += item}
end
p add_values(1,2,3,4) p add_values("a","b","c") p add_values([1,2,3],[4,5],
[6,7]) p add_values([1,2,3],[4,5,
[6,7]]) p add_values(1,2,3,"4") p add_values([1,2,3],[4,5,
[6,7]],8)
【出力】 10 "abc" [1, 2, 3, 4, 5,
6, 7] [1, 2, 3, 4, 5,
[6, 7]] TypeError TypeError
injectメソッド繰り返し計算を行う
メソッドの戻り値はブロックが最後に返した値
動的型
変数にどのクラスのオブジェクトが格納されているかは、実行時に初めてわかります
このような言語を動的型言語と呼ぶ
【コード】 x = (rand(2) == 0) ? "123456" :
123456
puts x.class
x = nil puts x.class
puts y.class
【出力】 String NilClass NameError
継承
前回触れているので簡単に スーパークラスとサブクラスの親子関係があります
Objectクラスは全てのクラスのスーパークラスです
サブクラスはスーパークラスのメソッドを使ったり、上書きしたり、新たにメソッドを追加したりできます
Rubyにおける継承は単一継承です
Mix-in
モジュールを取り込むことでクラスを拡張する仕組みです
多重継承の代わりの機能です 例えば、複数のクラスで使える
sort,map,find,rejectメソッドなどはEnumerableモジュールで定義されています
モジュール
モジュールは定数やメソッドを定義できる クラス変数のようなものを宣言したり、インスタンスやサブクラスのようなものを作ることはできない
関数のように実行することもできます (モジュール関数) 【コード】
puts Math.sqrt(2) 【出力】
1.4142135623731
モジュールの定義
【コード】 module Gleeting
def sayHello puts "hello" end
def sayGoodbye puts “goodbye" end
end
module モジュール名
メソッド定義
Incrude
モジュールの実装 (定数、メソッドなど )を クラスや別のモジュールに取り込みます
モジュールの include
【コード】 class Foo
include Greeting
def say puts " foo" end
end
a = Foo.new a.say a.sayHello
【出力】 foo hello
include
extend
includeはクラスにモジュールを実装するが、 extendはオブジェクトにモジュールを実装します
モジュールのメソッドはオブジェクトの特異メソッドとして追加されます
モジュールの extend
【コード】 module Wareki def heisei return self.year - 1988 end end
t1 = Time.local(2011,12,22) t2 = Time.local(2011,12,22)
t1.extend Wareki
p t1.heisei p t2.heisei
【出力】 23 NoMethodError
モジュール関数【コード】 module Gleeting def sayHello puts "hello" end module_function :sayHello end
class Foo include Greeting def say puts "foo" end end
puts Math.sqrt(2) a = Foo.new Gleeting.sayHello a.sayHello
【出力】 1.4142135623731 hello NoMethodErrorモジュールの定義
モジュール関数の設定
クラスの定義
include
モジュールの定数【コード】 module Gleeting ASA = “朝 " def sayHello puts "hello" end end
puts Gleeting::ASA Gleeting::ASA =
"morning" puts Gleeting::ASA
【出力】 warning: already
initialized constant ASA
朝 morning
以上