实例变量
本课属于 Coddy Ruby 学习旅程的“面向对象编程”单元。第 13 课,共 57 课。
类也是一个对象,因此它也可以有自己的实例变量。在类体中,@issued = 0 中的 self 是类本身,因此这个变量属于类,而不属于任何实例。类方法可以读取和修改它:
class Ticket
@issued = 0
def self.issue
@issued += 1
end
def self.issued
@issued
end
end
Ticket.issue
Ticket.issue
puts Ticket.issued输出:
2在 class << self 中使用 attr_accessor,会在类上生成读取器和设置器。之后,实例可以通过 self.class 访问类的状态,例如统计 new 创建的所有对象:
class Robot
@built = 0
class << self
attr_accessor :built
end
attr_reader :serial
def initialize
self.class.built += 1
@serial = self.class.built
end
end
a = Robot.new
b = Robot.new
puts "#{a.serial} #{b.serial} #{Robot.built}"输出:
1 2 2Ruby 还有类变量,写作 @@name。类变量由类及其所有实例共享,因此实例方法可以直接读取它:
class Player
@@count = 0
def initialize
@@count += 1
end
def self.count
@@count
end
def others
@@count - 1
end
end
Player.new
last = Player.new
puts Player.count
puts last.others输出:
2
1类变量也会与每个子类共享(基于另一个类构建的类,第 5 章),因此子类为它赋值时,也会改变父类中的值。类实例变量在每个类中彼此独立,因此大多数 Ruby 代码更倾向于使用它:
class Base
@@kind = "base"
@label = "base"
class << self
attr_reader :label
end
def self.kind
@@kind
end
end
class Child < Base
@@kind = "child"
@label = "child"
end
puts Base.kind
puts Base.label
puts Child.label输出:
child
base
child挑战
简单补全类 Ticket。每张新票都会获得下一个编号,从 1 开始,编号由类实例变量中的计数器保存。Ticket.issued 返回自上次重置以来已发出的票数,Ticket.reset 会将计数器重置为 0。to_s 返回 #3 Concert。
提供的代码会读取多行内容。reset 会重置计数器;其他任何一行都是活动名称,代码会据此创建一张票并将其打印出来。最后会打印 issued: 2。
你的代码写在 ticket.rb 中。main.rb 包含提供的输入/输出代码,不能编辑。
亲手试试
require_relative 'ticket'
# 提供的输入输出代码:保持原样。
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
if line == "reset"
Ticket.reset
else
puts Ticket.new(line)
end
end
puts "issued: #{Ticket.issued}"
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Ruby 在线编译器