Ruby类,子类和工厂方法

时间:2014-03-22 10:39:21

标签: ruby class hash subclass

我正在进行TestFirst练习(temperature_object),并且在集成子类时已经停滞不前了。到目前为止我已经:

class Temperature

    def initialize(opts = {})
        @options = opts
        @c = @options[:c]
        @f = @options[:f]
    end

    def self.from_celsius(num)
        self.new(:c => num)
    end

    def self.from_fahrenheit(num)
        self.new(:f => num)
    end

    def in_celsius
        if @options.has_key?(:c)
            @c
        elsif @options.has_key?(:f)
            ctof(@f)
        end
    end

    def in_fahrenheit
        if @options.has_key?(:f)
            @f
        elsif @options.has_key?(:c)
            ftoc(@c)
        end
    end

    def ftoc(num)
        (((num * 9) / 5.000) + 32)
    end

    def ctof(num)
        (((num - 32) * 5) / 9.0000)
    end


end

class Celsius < Temperature

    def initialize(num)

        @c = num

    end
end

class Fahrenheit < Temperature

    def initialize(num)

        @f = num

        end
end

所有测试都通过,直到我达到以下条件:

require "temperature_object"

describe Temperature do

    # Here's another way to solve the problem!
    describe "Temperature subclasses" do
        describe "Celsius subclass" do
            it "is constructed in degrees celsius" do
                Celsius.new(50).in_celsius.should == 50
                Celsius.new(50).in_fahrenheit.should == 122
            end

            it "is a Temperature subclass" do
                Celsius.new(0).should be_a(Temperature)
            end
        end

        describe "Fahrenheit subclass" do
            it "is constructed in degrees fahrenheit" do
                Fahrenheit.new(50).in_fahrenheit.should == 50
                Fahrenheit.new(50).in_celsius.should == 10
            end

            it "is a Temperature subclass" do
                Fahrenheit.new(0).should be_a(Temperature)
            end
        end
    end

end

所以,我认为问题在于我试图从使用散列的Temperature.new转到Celsius.new,它只取一个值。我收到了undefined method "has_key?" for nil:NilClass错误消息。我是否需要将num设置为哈希值并为其分配密钥?如果是这样,我该怎么做?如果没有,有什么建议吗?

1 个答案:

答案 0 :(得分:2)

您的问题是您引用了@options,但在创建Celsius的实例时没有指定它。您应该在继承的类中调用super构造函数:

class Celsius < Temperature  
  def initialize(num)
    super(c: num)
  end
end

class Fahrenheit < Temperature 
  def initialize(num)
    super(f: num)
  end
end

现在,当您拨打Celsius.new(50)时,initialize(opts)会被呼叫,就像您拨打Temperature.new(c: 50)一样,并且所有成员都将被正确分配。