Diferencia entre las variables de clase y las variables de instancia de clase?

¿Alguien puede decirme sobre la diferencia entre las variables de clase y las variables de instancia de clase?

Una variable de clase ( @@ ) se comparte entre la clase y todos sus descendientes. Los descendientes de la clase no comparten una variable de instancia de clase ( @ ).


Variable de clase ( @@ )

Tengamos una clase Foo con una variable de clase @@i , y accesadores para leer y escribir @@i :

 class Foo @@i = 1 def self.i @@i end def self.i=(value) @@i = value end end 

Y una clase derivada:

 class Bar < Foo end 

Vemos que Foo y Bar tienen el mismo valor para @@i :

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

Y cambiar @@i en uno lo cambia en ambos:

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

Variable de instancia de clase ( @ )

Hagamos una clase simple con una variable de instancia de clase @i y @i para leer y escribir @i :

 class Foo @i = 1 def self.i @i end def self.i=(value) @i = value end end 

Y una clase derivada:

 class Bar < Foo end 

Vemos que aunque Bar hereda los @i de @i para @i , no hereda @i mismo:

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

Podemos establecer la @i de Bar sin afectar la @i de Foo:

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

Primero debe comprender que las clases también son instancias, instancias de la clase Class .

Una vez que comprenda eso, puede comprender que una clase puede tener variables de instancia asociadas con ella, al igual que un objeto regular (de lectura: no de clase).

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

Tenga en cuenta que una variable de instancia en Hello está relacionada y es distinta de una variable de instancia en una instancia de 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!" 

Una variable de clase, por otro lado, es un tipo de combinación de los dos anteriores, ya que está accesible en Hello y sus instancias, así como en las subclases de Hello y sus instancias:

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

Muchas personas dicen que se deben evitar class variables debido al extraño comportamiento anterior, y recomiendan el uso de class instance variables de class instance variables lugar.

    Intereting Posts