2015-06-20 130 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