Menu
CoddyTech

Zmienne instancji klasy

Część sekcji Programowanie obiektowe ścieżki Ruby w Coddy. Lekcja 13 z 57.

Klasa też jest obiektem, więc może mieć własne zmienne instancji. @issued = 0 w ciele klasy, gdzie self oznacza klasę, należy do klasy, a nie do żadnej instancji. Metody klasowe odczytują tę zmienną i ją zmieniają:

class Ticket
  @issued = 0

  def self.issue
    @issued += 1
  end

  def self.issued
    @issued
  end
end

Ticket.issue
Ticket.issue
puts Ticket.issued

Wynik:

2

attr_accessor wewnątrz class << self tworzy metodę odczytującą i ustawiającą w klasie. Instancje mogą wtedy uzyskać dostęp do stanu klasy za pośrednictwem self.class, na przykład aby zliczać każdy obiekt utworzony przez 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}"

Wynik:

1 2 2

Ruby ma również zmienne klasowe, zapisywane jako @@name. Zmienna klasowa jest współdzielona przez klasę i wszystkie jej instancje, więc metody instancji mogą odczytywać ją bezpośrednio:

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

Wynik:

2
1

Zmienna klasowa jest również współdzielona z każdą podklasą (klasą zbudowaną na podstawie innej klasy, rozdział 5), więc podklasa, która przypisuje jej wartość, zmienia ją także dla klasy nadrzędnej. Zmienna instancji klasy pozostaje osobna dla każdej klasy, dlatego większość kodu Ruby ją preferuje:

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

Wynik:

child
base
child
challenge icon

Wyzwanie

Łatwy

Uzupełnij klasę Ticket. Każdy nowy bilet otrzymuje kolejny numer, zaczynając od 1, z licznika przechowywanego w zmiennej instancji klasy. Ticket.issued zwraca liczbę biletów wydanych od ostatniego resetu, a Ticket.reset ustawia licznik z powrotem na 0. to_s zwraca #3 Concert.

Dostarczony kod odczytuje wiersze. reset resetuje licznik; każdy inny wiersz jest nazwą wydarzenia, dla którego tworzy bilet i go wyświetla. Na końcu wyświetla issued: 2.

Twój kod umieść w pliku ticket.rb. main.rb zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.

Spróbuj swoich sił

require_relative 'ticket'

# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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 iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Ruby online