读取器与写入器
本课属于 Coddy Ruby 学习旅程的“面向对象编程”单元。第 7 课,共 57 课。
为每个实例变量编写读取方法会很重复。在类体中使用 attr_reader :title 会生成方法 title,它会返回 @title。一行可以列出多个名称:
class Book
attr_reader :title, :pages
def initialize(title, pages)
@title = title
@pages = pages
end
end
book = Book.new("Dune", 412)
puts book.title
puts book.pages输出:
Dune
412attr_writer :title 会生成一个setter(设置器),即方法 title=,它会将参数存储到 @title 中。Ruby 允许你使用赋值语法调用它:book.title = "Emma":
class Book
attr_reader :title
attr_writer :title
def initialize(title)
@title = title
end
end
book = Book.new("Dune")
book.title = "Dune Messiah"
puts book.title输出:
Dune Messiahattr_accessor 会同时生成读取器和设置器。有了这两者,+= 这样的简写也能使用,因为 player.score += 5 表示 player.score = player.score + 5:
class Player
attr_accessor :name, :score
def initialize(name)
@name = name
@score = 0
end
end
ada = Player.new("Ada")
ada.score += 5
ada.score += 3
ada.name = "Ada L."
puts "#{ada.name}: #{ada.score}"输出:
Ada L.: 8尽量少暴露属性。对于外部代码可以读取但不能修改的值,使用 attr_reader;只有在设计上允许从外部修改值时,才添加 writer。给只有读取器的属性赋值会引发 NoMethodError:
class Book
attr_reader :title
def initialize(title)
@title = title
end
end
book = Book.new("Dune")
begin
book.title = "Emma"
rescue NoMethodError => e
puts e.message
end
puts book.title输出:
undefined method `title=' for an instance of Book
Dune挑战
简单完成 Book 类。外部代码可以读取 title、author 和 pages,也可以读取和更改 pages_read,它的初始值为 0。progress 返回 Dune: 120/412 (29%),百分比向下取整。
提供的代码会根据输入的前三行(标题、作者、页数)创建一本书。之后的每一行都是读者读完的页数;代码会将每个数字加到 book.pages_read += n。最后,它会打印 Dune by Frank Herbert 和阅读进度。
你的代码写在 book.rb 中。main.rb 包含提供的输入/输出代码,不能编辑。
亲手试试
require_relative 'book'
# 提供的输入输出代码:保持原样
input = []
while (line = gets)
input << line.chomp
end
book = Book.new(input[0], input[1], input[2].to_i)
input.drop(3).each { |n| book.pages_read += n.to_i }
puts "#{book.title} by #{book.author}"
puts book.progress
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Ruby 在线编译器