类变量和继承。子类的具体变量?

时间:2018-04-16 00:39:59

标签: ruby

我对子类和类变量有点挣扎。我期望通过子类的类方法调用设置的类变量特定于该子类,但我看到它们是在超类中设置的。

例如,如果我运行以下代码:

class Obj
    @@can_say = []
    def self.says word
        @@can_say.push(word)
    end

    def self.listens_to calling
        define_method calling do
            "I say #{@@can_say}"
        end
    end
end

class Dog < Obj
    says "woof"
    says "bark bark"
    listens_to "goodboy"
end

class Cat < Obj
    says "meaow"
    says "purr"
    listens_to "lord"
end

cat = Cat.new
dog = Dog.new

puts("Dog: #{dog.goodboy}")
puts("Cat: #{cat.lord}")

我明白了:

ruby/test$ ruby test.rb 
Dog: I say ["woof", "bark bark", "meaow", "purr"]
Cat: I say ["woof", "bark bark", "meaow", "purr"]

我在期待:

ruby/test$ ruby test.rb 
Dog: I say ["woof", "bark bark"]
Cat: I say ["meaow", "purr"]

有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:0)

我找到了一种方法:

class Obj
    class << self
        attr_accessor :can_say
    end

    def self.says word
        if @can_say.nil?
            @can_say = Array.new
        end
        @can_say.push(word)
    end

    def self.listens_to calling
        define_method calling do
            "I say #{self.class.can_say}"
        end
    end
end

class Dog < Obj
    says "woof"
    says "bark bark"
    listens_to "goodboy"
end

class Cat < Obj
    says "meaow"
    says "purr"
    listens_to "lord"
end

cat = Cat.new
dog = Dog.new

puts("Dog: #{dog.goodboy}")
puts("Cat: #{cat.lord}")

现在,如果我能以某种方式摆脱:

if @can_say.nil?
    @can_say = Array.new
end