¿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 @@i
y 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 @@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 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 @i
sí mismo:
p Foo.i # => 1
p Bar.i # => nil
Podemos configurar Bar's @i
sin 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
Class
clase.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
Hello
está relacionada y es distinta de una variable de instancia en una instancia deHello
Una variable de clase, por otro lado, es una especie de combinación de las dos anteriores, ya que es accesible en
Hello
sí misma y sus instancias, así como en subclases deHello
y sus instancias:Muchas personas dicen que se debe evitar
class variables
debido 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#class
usos se usan cuando se llama a cualquier cosa que noself
sean olores de código. Incluso puede ir un paso más allá e implementar accesos de instanciai
yi=
delegar a sus#class
equivalentes, 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.