Menu
CoddyTech

类方法

本课属于 Coddy Ruby 学习旅程的“面向对象编程”单元。第 12 课,共 57 课。

类方法属于类,而不属于某个实例。在类体中,self 是类本身,因此 def self.name 会在类上定义一个方法。你可以直接在类上调用它:

class Temperature
  def self.to_fahrenheit(celsius)
    celsius * 9 / 5.0 + 32
  end
end

puts Temperature.to_fahrenheit(100)
puts Temperature.to_fahrenheit(-40)

输出:

212.0
-40.0

类方法和实例方法位于不同的位置。实例不能直接调用类方法,而是通过 self.class 或类名来调用:

class Circle
  def self.area_for(r)
    (3.14159 * r * r).round(2)
  end

  def initialize(r)
    @r = r
  end

  def area
    self.class.area_for(@r)
  end
end

puts Circle.area_for(1)
puts Circle.new(2).area
begin
  Circle.new(2).area_for(2)
rescue NoMethodError => e
  puts e.message
end

输出:

3.14
12.57
undefined method `area_for' for an instance of Circle

class << self 会在类主体中打开一个区域,其中的每个 def 都是类方法。当一个类有多个类方法时,这样可以省去写 self.:

class Units
  class << self
    def km_to_miles(km)
      (km * 0.621371).round(1)
    end

    def miles_to_km(miles)
      (miles / 0.621371).round(1)
    end
  end
end

puts Units.km_to_miles(10)
puts Units.miles_to_km(26.2)

输出:

6.2
42.2

如果要处理属于某一类事物,而不是某个对象的工作,例如转换单位、将文本解析为对象,或统计所有实例的数量,就使用类方法。需要使用某个对象的数据时,则使用实例方法:

class Invoice
  def self.tax_rate      # 每张发票都一样
    0.2
  end

  def tax                # 需要这张发票的金额
    @amount * Invoice.tax_rate
  end
end
challenge icon

挑战

简单

补全 Temperature 的类方法。to_fahrenheit(c) 和 to_celsius(f) 用于转换一个值。feel(celsius) 在低于 0 时返回 freezing,低于 15 时返回 cold,低于 25 时返回 mild,其他情况返回 hot。convert(text) 接收 20 C 或 68 F 这样的文本,并返回 20.0 C = 68.0 F (mild) 或 68.0 F = 20.0 C (mild),数值保留一位小数,并根据摄氏值返回对应的体感;该方法会调用其他类方法。

提供的代码会针对每一行输入调用 Temperature.convert(line),并打印结果。不会创建 Temperature 的实例。

请将代码写在 temperature.rb 中。main.rb 中包含提供的输入输出代码,不能修改。

亲手试试

require_relative 'temperature'

# 提供的输入和输出代码:保持原样
input = []
while (line = gets)
  input << line.chomp
end
input.each { |line| puts Temperature.convert(line) }
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Ruby 在线编译器