Make the base class meaningful
Right now you've declared Temperature
as a base class, but all it really does is set up your two variables. One way to utilize it more would be to assign a unit of some sort to the class (I've chosen Kelvin, but it could have been anything).
In my version, Temperature
stores everything as Kelvin. Any class that inherits from it only has to know how to convert back and forth to Kelvin (So Celsius<->Kelvin and Fahrenheit<->Kelvin). Later, if I wanted to add operators to add/subtract/compare temperatures, since the base units are all kelvin, everything is easy.
You'll also notice that I've moved has_temp?
to the base class and the threshold temperature is in Kelvin. This gives all sub-classes the functionality without having to know anything about where the theshold is, and likewise the base class will always work without needing to know the details of a particular unit of measure.
Finally, while I've used Kelvin as the unit for Temperature
, the base class could have just as easily been called Kelvin
.
class Temperature
attr_accessor :temp, :method
FEVER_THRESHOLD = 310.15 # 98.6F to K
def initialize(temp, method)
@temp = temp
@method =method
end
def to_s
"#{@temp} K"
end
def has_fever?
@temp > FEVER_THRESHOLD
end
end
class Celsius < Temperature
def self.to_k(value)
value + 273.15
end
def self.from_k(value)
value - 273.15
end
def initialize(temp, method)
super(Celsius.to_k(temp), method)
end
def to_s
"%0.2f C" % [Celsius.from_k(@temp)]
end
end
class Fahrenheit < Temperature
def self.to_k(value)
(value + 459.67) * (5.0/9.0)
end
def self.from_k(value)
(value * 9.0/5.0) - 459.67
end
def initialize(temp, method)
super(Fahrenheit.to_k(temp), method)
end
def to_s
"%0.2f F" % [Fahrenheit.from_k(@temp)]
end
end
#test Celsius
temp = Celsius.new(39, nil)
puts temp.to_s # 39.0 C
puts temp.has_fever? # true
#test Fahrenheit
temp = Fahrenheit.new(97.9, nil)
puts temp.to_s # 97.90 F
puts temp.has_fever? # false
On a personal note, I wouldn't necessarily use inheritance as my go-to solution for this problem without a lot more knowledge and thought about the use-cases; I only followed your initial design. Temperatures themselves are fairly trivial, but perhaps for a more complicated scenario this implementation would have advantages.