¿Alguien puede decirme sobre la diferencia entre las variables de clase y las variables de instancia de clase?
91
¿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 @@iy accesos 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 @@ien 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 @iy accesos 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 descriptores de acceso @i, no se hereda a @isí mismo:
p Foo.i # => 1
p Bar.i # => nil
Podemos configurar Bar's @isin afectar a Foo's @i:
Bar.i = 2
p Foo.i # => 1
p Bar.i # => 2
Primero debe comprender que las clases también son instancias, instancias de la
Classclase.Una vez que comprenda eso, puede comprender que una clase puede tener variables de instancia asociadas con ella al igual que un objeto normal (léase: no clase).
Tenga en cuenta que una variable de instancia en no
Helloestá relacionada y es distinta de una variable de instancia en una instancia deHelloUna variable de clase, por otro lado, es una especie de combinación de las dos anteriores, ya que es accesible en
Hellosí misma y sus instancias, así como en subclases deHelloy sus instancias:Muchas personas dicen que se debe evitar
class variablesdebido al comportamiento extraño anterior y recomiendan el uso declass instance variables.fuente
También quiero agregar que puede obtener acceso a la variable de clase (
@@) desde cualquier instancia de la clasePero no puede hacer lo mismo con la variable de instancia de clase (
@)fuente
Foo.i, pero ¿cómo puede hacer lo mismo para cada instancia de esta clase comoFoo.new.i?#class. Sin embargo, personalmente creo que los#classusos se usan cuando se llama a cualquier cosa que noselfsean olores de código. Incluso puede ir un paso más allá e implementar accesos de instanciaiyi=delegar a sus#classequivalentes, en cuyo caso puede hacerloFoo.new.i. No recomiendo hacer eso ya que crea una interfaz confusa, lo que sugiere que está modificando un miembro del objeto.