Ruby超入門 2周目 CHAPTER8-8 メソッドの呼び出しを 制限する まで

f:id:kkouji0224:20191029231558p:plain

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

よーしご飯食べて筋トレ終わったぜ!こんばんはkoujiです。

 

じゃーさっきの続きを振り返っていきまーっす!

 

継承でクラスを分ける

 

class Drink
    def name
        @name
    end
    def name=(text)
        @name = text
    end
    def size
        @size
    end
    def size=(text)
        @size =text
    end
end

class Alc < Drink
    def alcohol_content
        @alcohol_content
    end
    def alcohol_content=(text)
        @alcohol_content = text
    end
end

drink = Drink.new 
drink.name = "生"

alc = Alc.new
alc.name = "ビール"
alc.size = "中"
alc.alcohol_content = "5%"

 

上のプログラムの場合だとDrinkクラスをAlcクラスが継承してる感じだね。AlcクラスのスーパークラスがDrinkクラスだね。 見てのとおりなんだけど、AlcクラスはDrinkクラスを継承してるので、Drinkクラスで定義したnameとかname=(text)とかsizeも使えちゃう。便利だよね。なのでalc.nameとかalc.sizeとかDrinkクラスにしか書いてなくてもAlcクラスで使えちゃうっていう!

 

で、スーパークラスとサブクラスのどちらにメソッドを加えるかってことなんだけど、上の場合はアルコール度数はアルコールにしかないので、Alcクラスに加えてるって感じだね。

 

 

Rubyの用意しているクラスの継承関係

 

p Integer.ancestors
p Array.ancestors
p Class.ancestors

 

うえのancestorsメソッドを使うとクラスの継承関係が見れちゃう。こういうの面白いよね。なんかこうワクワクするのは僕だけでしょうか。

 

f:id:kkouji0224:20191103213002p:plain

 

ancestorsメソッドを実行するとこんな感じだね。最終的にBasicObjectにたどり着くね。このBasicObjectって一体何者なんだろう… 今は気にしないでおこう…

 

親子で同名のメソッドを作った時の動作は?

 

class Drink
    def name
        @name
    end
    def name=(text)
        @name = text
    end
    def size
        @size
    end
    def size=(text)
        @size = text
    end
    def full_name
        @name
    end
end

class Alc < Drink
    def alc_content
        @alc_content
    end
    def alc_content=(text)
        @alc_content = text
    end
    def full_name
        "#{@name} #{@alc_content} #{@size}サイズ"
    end
end

alc = Alc.new
alc.name = "生ビール"
alc.size = "中"
alc.alc_content = "5%"
puts alc.full_name

 

サブクラスのAlcクラスのオブジェクトにたいしてfull_nameメソッドを呼び出すと、Alcクラスのfull_nameメソッドが呼び出されるんだね。どんどん遡って最初にあったものが呼び出されるみたいだぜっ。

 

superで親クラスのメソッドを呼び出す

 

class Drink
    def name
        @name
    end
    def name=(text)
        @name = text
    end
    def size
        @size
    end
    def size=(text)
        @size = text
    end
    def full_name
        @name
    end
end

class Alc < Drink
    def alc_content
        @alc_content
    end
    def alc_content=(text)
        @alc_content = text
    end
    def full_name
        super
    end
end

alc = Alc.new
alc.name = "生ビール"
alc.size = "中"
alc.alc_content = "5%"
puts alc.full_name

 

サブクラスAlcクラスのfull_nameメソッドの中にsuperって書いてあげると、親クラスのこの場合Drinkクラスのfull_nameメソッドが呼び出されるんだね。superは親クラスの同名メソッドを呼び出して戻り値を返すんだね。だからこの場合は"生ビール"になるね。

 

クラスの中のメソッド定義の中だけで呼び出せるように制限

 

class Buddhism
    def buddha
        nirvana
    end
    private
    def nirvana
        "真理"
    end
end

buddhism = Buddhism.new
puts buddhism.buddha
puts buddhism.nirvana

 

 はい。また意味のわからない例えプログラムを書いてしまいました… 簡単にいうとbuddha(悟った人)しか真理にってことなんだけども… わかりにくくてすみませんねぇ。思いついたのがこれやねん。見ての通りだ。privateの下に書いてあるnirvanaメソッドはbuddhismってレシーバを指定しての呼び出しができなくなるんだね。で、buddhaメソッドの中からはnirvanaを呼び出して真理ってなる。哲学的だぜ…。

 

レシーバを指定しての呼び出しが禁止されたものをprivateメソッドで、レシーバに続けて書いて呼び出せるものをpublicメソッドっていうんだぜ。

 

上の書き方だと、privateから下はprivateメソッドになっちゃうんだけど、このメソッドだけみたいな書き方もできるんだね。

 

class Buddhism
    def buddha
        nirvana
    end
    private def nirvana
        "真理"
    end
end

 

こんな感じでdefの前にprivateを書いてあげると、そのメソッドだけprivateメソッドにできるんだぜっ。

 

プライベートなクラスメソッド

 

class Buddhism
    private_class_method def self.buddha
        "nirvana"
    end
end

p Buddhism.buddha

 

こんな感じで書いてあげるといいみたい。defの前にprivate_class_methodだね。

 

class Buddhism
    class << self
        private 
        def buddha
            "nirvana"
        end
    end
end

p Buddhism.buddha

 

 class << selfの書き方だとprivateが使えるのでこっちのほうが楽な感じかなぁ。

 

 

ってことでCHAPTER8の振り返りはこれで終わりだね。このCHAPTERが山場かなぁという感じだったのでそれが終わってしまうのは少し寂しい気持ちにもなるけど、Rubyの旅自体は終わらないので、まぁ良しとしましょうかね!!

 

とかいってるけどこの超入門はCHAPTER11まであるので気は抜かずに楽しんでいくぜ。

 

ってことで今日はこの辺でアディオス!