私有方法
本课属于 Coddy Ruby 学习旅程的“面向对象编程”单元。第 17 课,共 57 课。
封装是指对象隐藏其工作原理,并提供一小组公共方法。方法默认是公共的。在类主体中,private 之后定义的每个方法都是私有方法:对象自身的方法可以调用它,外部代码则不能:
class Order
def initialize(price, quantity)
@price = price
@quantity = quantity
end
def total
subtotal + shipping
end
private
def subtotal
@price * @quantity
end
def shipping
subtotal >= 50 ? 0 : 5
end
end
order = Order.new(10, 3)
puts order.total
begin
order.subtotal
rescue NoMethodError => e
puts e.message
end输出:
35
private method `subtotal' called for an instance of Order在类内部,调用私有方法时不需要接收者,也可以使用 self.。即使另一个对象属于同一个类,也不能对它调用这个方法:
class Coin
def initialize(cents)
@cents = cents
end
def describe
"#{self.label} / #{label}"
end
def same_as?(other)
other.label == label
end
private
def label
"#{@cents}c"
end
end
a = Coin.new(5)
puts a.describe
begin
a.same_as?(Coin.new(5))
rescue NoMethodError => e
puts e.message
end输出:
5c / 5c
private method `label' called for an instance of Coinprivate 也可以接收方法名,而 def 会返回方法名,因此 private def helper 会在定义的位置将单个方法设为私有。它上方和下方的方法仍然是公有的:
class Greeter
def greet(name)
"#{salutation}, #{name}!"
end
private def salutation
"Hello"
end
def wave
"*waves*"
end
end
g = Greeter.new
puts g.greet("Ada")
puts g.wave
p Greeter.private_instance_methods(false)输出:
Hello, Ada!
*waves*
[:salutation]将辅助方法设为私有。公有方法是类对程序其他部分作出的承诺;之后可以重命名或删除私有方法,而不会影响任何调用者:
class Invoice
def total # 公开:调用方依赖它
net + tax
end
private # 以后可以随时修改
def net
...
end
def tax
...
end
end挑战
简单完成 Order 类。除了 initialize,它唯一的公共方法是 receipt,该方法返回 3 x 12.50 = 37.50, tax 7.50, total 45.00。私有方法 subtotal(价格乘以数量)、tax(小计的 20%)和 total 用于计算这些数字。
提供的代码会将订单读取为 quantity price 格式的行,并打印每张收据。然后,它会尝试从外部调用 tax,当 Ruby 拒绝时打印 tax is private。
你的代码写在 order.rb 中。main.rb 包含提供的输入/输出代码,不能编辑。
亲手试试
require_relative 'order'
# 已提供的输入输出代码:保持原样。
input = []
while (line = gets)
input << line.chomp
end
orders = input.map do |line|
quantity, price = line.split
Order.new(quantity.to_i, price.to_f)
end
orders.each { |o| puts o.receipt }
begin
orders[0].tax
puts "tax is public"
rescue NoMethodError
puts "tax is private"
end
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Ruby 在线编译器