Разница между переменными класса и переменными экземпляра класса?



может ли кто-нибудь рассказать мне о разнице между переменными класса и переменными экземпляра класса?

549   2  

2 ответов:

переменной класса (@@) является общим для класса и всех его потомков. Переменная экземпляра класса (@) не является общим для потомков класса.


переменной класса (@@)

давайте класс Foo с переменной класса @@i, и методы доступа для чтения и записи @@i:

class Foo

  @@i = 1

  def self.i
    @@i
  end

  def self.i=(value)
    @@i = value
  end

end

и производный класс:

class Bar < Foo
end

мы видим, что foo и Bar имеют одинаковое значение для @@i:

p Foo.i    # => 1
p Bar.i    # => 1

и изменение @@i в одном изменения в:

Bar.i = 2
p Foo.i    # => 2
p Bar.i    # => 2

переменной экземпляра класса (@)

давайте сделаем простой класс с переменной экземпляра класса @i и аксессоры для чтения и записи @i:

class Foo

  @i = 1

  def self.i
    @i
  end

  def self.i=(value)
    @i = value
  end

end

и производный класс:

class Bar < Foo
end

мы видим, что хотя бар наследует методы доступа для @i, он не наследует @i сам по себе:

p Foo.i    # => 1
p Bar.i    # => nil

мы можем установить бар @i не затрагивая Фу @i:

Bar.i = 2
p Foo.i    # => 1
p Bar.i    # => 2

сначала вы должны понять, что классы тоже являются экземплярами-экземпляры Class класса.

как только вы это поймете, вы можете понять, что класс может иметь переменные экземпляра, связанные с ним так же, как и обычный (читай: неклассовый) объект.

Hello = Class.new

# setting an instance variable on the Hello class
Hello.instance_variable_set(:@var, "good morning!")

# getting an instance variable on the Hello class
Hello.instance_variable_get(:@var) #=> "good morning!"

обратите внимание, что переменная экземпляра на Hello полностью не связан и отличается от переменной экземпляра на экземпляр на Hello

hello = Hello.new

# setting an instance variable on an instance of Hello
hello.instance_variable_set(:@var, :"bad evening!")

# getting an instance variable on an instance of Hello
hello.instance_variable_get(:@var) #=> "bad evening!")

# see that it's distinct from @var on Hello
Hello.instance_variable_get(:@var) #=> "good morning!"

A переменной класс С другой стороны-это своего рода комбинация этих двух, как он работает на и его экземпляры, а также на подклассы Hello и их экземпляров:

HelloChild = Class.new(Hello)
Hello.class_variable_set(:@@class_var, "strange day!")
hello = Hello.new
hello_child = HelloChild.new

Hello.class_variable_get(:@@class_var) #=> "strange day!"
HelloChild.class_variable_get(:@@class_var) #=> "strange day!"
hello.singleton_class.class_variable_get(:@@class_var) #=> "strange day!"
hello_child.singleton_class.class_variable_get(:@@class_Var) #=> "strange day!"

многие говорят, чтобы избежать class variables из-за странного поведения выше, и рекомендуют использовать .

Comments

    Ничего не найдено.