方法与 self
本课属于 Coddy Ruby 学习旅程的“面向对象编程”单元。第 4 课,共 57 课。
方法可以在不写接收者的情况下调用同一对象的另一个方法。Ruby 会将调用发送给当前对象,因此各个方法可以相互配合:
class Order
def initialize(price, quantity)
@price = price
@quantity = quantity
end
def subtotal
@price * @quantity
end
def shipping
subtotal >= 50 ? 0 : 5
end
def total
subtotal + shipping
end
end
puts Order.new(10, 3).total
puts Order.new(20, 3).total输出:
35
60在方法内部,self 是调用该方法的对象。返回 self 的方法可以让调用者在同一个对象上连续调用多个方法:
class Counter
def initialize
@count = 0
end
def add(n)
@count += n
self
end
def count
@count
end
end
puts Counter.new.add(2).add(5).count输出:
7对象还可以通过 self 将自身交给其他代码,例如,在与另一个同类对象进行比较时,返回胜出者:
class Player
def initialize(name, score)
@name = name
@score = score
end
def name
@name
end
def score
@score
end
def winner_against(other)
score >= other.score ? self : other
end
end
ada = Player.new("Ada", 9)
bo = Player.new("Bo", 7)
puts ada.winner_against(bo).name
puts bo.winner_against(ada).name输出:
Ada
Ada用于回答是或否的问题的方法名以 ? 结尾,例如 empty?。参数可以有默认值,当调用者省略参数时,就会使用默认值:
class Kettle
def initialize
@temp = 20
end
def hot?
@temp >= 90
end
def heat(degrees = 10)
@temp = [@temp + degrees, 100].min
end
end
k = Kettle.new
k.heat
puts k.hot?
k.heat(75)
puts k.hot?输出:
false
true挑战
简单完成 ShoppingCart 类。add(name, price) 会存储一件商品并返回购物车本身,因此可以链式调用。total 会返回价格总和,free_shipping? 会在总额达到 20 时返回 true,summary 会返回 3 items, total 12.50(或 1 item, total 4.00),并保留两位小数。
提供的代码会为每行输入(name price)添加一件商品,并通过链式调用完成操作,然后输出 summary 和 free shipping: true 或 free shipping: false。
请将代码写在 shopping_cart.rb 中。main.rb 包含提供的输入/输出代码,不能编辑。
亲手试试
require_relative 'shopping_cart'
# 提供的输入和输出代码:保持原样
input = []
while (line = gets)
input << line.chomp
end
cart = input.reduce(ShoppingCart.new) do |c, line|
name, price = line.split
c.add(name, price.to_f)
end
puts cart.summary
puts "free shipping: #{cart.free_shipping?}"
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Ruby 在线编译器