Menu
CoddyTech

Biến thực thể của lớp

Thuộc phần Lập trình hướng đối tượng trong hành trình Ruby của Coddy. Bài học 13 trên 57.

Lớp cũng là một đối tượng, nên nó có thể có các biến thực thể riêng. @issued = 0 trong thân lớp, nơi self là lớp, thuộc về lớp chứ không thuộc về bất kỳ đối tượng nào. Các phương thức lớp đọc và thay đổi biến này:

class Ticket
  @issued = 0

  def self.issue
    @issued += 1
  end

  def self.issued
    @issued
  end
end

Ticket.issue
Ticket.issue
puts Ticket.issued

Đầu ra:

2

attr_accessor bên trong class << self tạo một phương thức đọc và một phương thức thiết lập trên lớp. Sau đó, các đối tượng truy cập trạng thái của lớp thông qua self.class, chẳng hạn như để đếm mọi đối tượng mà new tạo ra:

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}"

Đầu ra:

1 2 2

Ruby cũng có biến lớp, được viết là @@name. Biến lớp được lớp và tất cả các đối tượng của lớp đó dùng chung, nên các phương thức thực thể có thể đọc trực tiếp biến này:

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

Đầu ra:

2
1

Biến lớp cũng được chia sẻ với mọi lớp con (một lớp được xây dựng dựa trên lớp khác, chương 5), vì vậy khi lớp con gán giá trị cho biến đó, giá trị trong lớp cha cũng thay đổi. Biến thực thể cấp lớp vẫn riêng biệt trong mỗi lớp, vì vậy hầu hết code Ruby đều ưu tiên cách này:

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

Đầu ra:

child
base
child
challenge icon

Thử thách

Dễ

Hoàn thiện lớp Ticket. Mỗi vé mới nhận số tiếp theo, bắt đầu từ 1, từ bộ đếm được lưu trong biến thực thể của lớp. Ticket.issued trả về số vé đã phát hành kể từ lần đặt lại gần nhất, còn Ticket.reset đặt bộ đếm về 0. to_s trả về #3 Concert.

Code được cung cấp đọc từng dòng. reset đặt lại bộ đếm; mọi dòng khác là tên một sự kiện, code sẽ tạo vé cho sự kiện đó rồi in vé ra. Cuối cùng, code in ra issued: 2.

Đặt code của bạn trong ticket.rb. main.rb chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.

Tự làm thử

require_relative 'ticket'

# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
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}"
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Ruby online