2015-06-20 183 views
1

我使用super將參數傳遞給父initialize方法,該方法默認情況下未調用。這就是它的樣子。 (請注意,在最後兩個參數使用superRuby類初始化覆蓋模塊初始化

module Pet 
    def initialize name, is_pet 
    @is_pet = is_pet 
    if is_pet 
     @name = name 
    else 
     @name = "Unnamed" 
    end 
    end 
    def pet? 
    return @is_pet 
    end 
    def get_name 
    return @name 
    end 
end 

class Dog 
    include Pet 
    def initialize tricks, name, is_pet 
    @tricks = tricks 
    super name, is_pet 
    end 
    def get_tricks 
    return @tricks 
    end 
end 

這裏是我可以用它做:

d = Dog.new ["roll", "speak", "play dead"], "Spots", true 

d.pet?  #=> true 
d.get_tricks #=> ["roll", "speak", "play dead"] 
d.get_name #=> "Spots" 

它工作正常,但我只是想知道是否有更好的方法做這個。

回答

1
  • 這不是一個良好的編程習慣硬編碼一個固定的字符串像"Unnamed"@name值。在這種情況下,您應該分配nil,並在打印時進行任何修改。假設你這樣做。

  • 然後is_pet可以從name是否爲nil推導出來,所以將它作爲實例變量是多餘的。您只需將!!應用於name即可獲得is_pet。因此,你應該擺脫這樣的實例變量。

  • 您有get_前綴作爲getter方法,但在Ruby中,最好使用與實例變量(不帶atmark)相同的名稱作爲getter名稱。

這會給你:

module Pet 
    attr_reader :name 
    def initialize name; @name = name end 
end 

class Dog 
    include Pet 
    attr_reader :tricks 
    def initialize tricks, name 
    @tricks = tricks 
    super(name) 
    end 
end 

d = Dog.new ["roll", "speak", "play dead"], "Spots" 
d.tricks #=> ["roll", "speak", "play dead"] 
d.name #=> "Spots" 
!!d.name #=> true (= `is_pet`) 
+0

謝謝你,非常有用 – hexagonest

0

不要編寫調用super進入一個包含模塊代碼。不要編寫期望孩子稱呼超級的模塊。這不是模塊的要點。

這是很好的面向對象的風格,不問問什麼是事情。看起來「告訴,不要問」,並在一般鴨子打字。

如果你想提供一個默認的initialize方法,你的可能想要繼承。但是偶爾會有一些有效的用例來覆蓋模塊中的初始化。慣用的事情做的,是一個鉤子方法:

module Pet 
    def initialize(options = {}) 
    @name = options[:name] 
    post_initialize(options) 
    end 

    def post_initialize(options = {}) 
    # can be overridden in including modules 
    end 
end 

class Dog 
    include Pet 

    def post_initialize(options = {}) 
    @tricks = options[:tricks] 
    end 
end 

dog = Dog.new(name: "Fido", tricks: ["play dead", "roll over"]) 

模塊是包括在許多不同的事情一些共享行爲。把它看作是一個形容詞,描述你可以用一個包含它的類來做什麼,這是很好的。以「 - 」結尾的單詞(如EnumerableComparable)描述了一個接收類或「 - 或」(Iterator,Interactor),描述了一個課程,是模塊的良好選擇。

+0

我使用模塊來做到這一點的原因是因爲我有多個類從「哺乳動物」類繼承。狗是從「哺乳動物」繼承,所以我不能也從寵物繼承。另外,寵物更多的是毯子,而不是物體,我認爲這就是模塊所做的。 – hexagonest