variable programacion privados orientada objetos multiple lenguaje herencia ejemplos con clases clase atributos ruby class inheritance class-variables

privados - programacion con objetos ruby



Variables de clase Ruby (5)

Las cosas de la clase de Ruby me están dando dolor de cabeza. Entiendo dado esto ...

class Foo @var = ''bar'' end

... que @var es una variable en la instancia de la clase creada.

Pero, ¿cómo creo una variable de clase invalidable de subclase?

Aquí hay un ejemplo de lo que haría en Python:

class Fish: var = ''fish'' def v(self): return self.var class Trout(Fish): var = ''trout'' class Salmon(Fish): var = ''salmon'' print Trout().v() print Salmon().v()

Qué salidas:

trout salmon

¿Cómo hago lo mismo en ruby?


Aquí está la versión que terminé averiguando usando el enlace de hobodave:

class Fish class << self attr_accessor :var end @var = ''fish'' def v self.class.var end end class Trout < Fish @var = ''trout'' end class Salmon < Fish @var = ''salmon'' end puts (Trout.new).v # => trout puts (Salmon.new).v # => salmon

Tenga en cuenta que la @var subclases solo requiere la adición de un @var , no es necesario anular la inicialización.


Es un error común que hacen los programadores de Java al llegar a Ruby, y uno de los grandes saltos conceptuales que tuve que hacer para entenderlo. Al principio parece extraño, pero en realidad es uno de los aspectos más interesantes de Ruby: todo el código es ejecutable, incluidas las definiciones de clases.

Por lo tanto, las variables de instancia deben declararse dentro de los métodos. Tiene que ver con cómo se evalúa el "yo". ''uno mismo'' es el objeto actual. El intérprete buscará las llamadas al método y las referencias de variables primero en ''self'':

class Fish @var = "foo" # here ''self'' == Fish, the constant which contains the class object def foo # do foo end end fish = Fish.new fish.foo # here ''self'' == fish, an instance of Fish

En una definición de clase, ''self'' se configura como el objeto de clase que se está definiendo, por lo que cualquier referencia dentro de una definición de clase se referirá a ese objeto de clase, en este caso Fish.

Sin embargo, cuando se invoca un método en una instancia de Fish, el self se establece para ser el receptor de la llamada, la instancia particular de Fish. Entonces, fuera de una definición de método, el yo es el objeto de clase. Dentro de un método, self es la instancia del receptor. Esta es la razón por la cual @var fuera de una definición de método es más parecido a una variable estática en Java, y @var dentro de una definición de método es una variable de instancia.


Hay un problema: puede anular @var:
Salmon.var = ''shark'' anulará @var, por lo
puts (Salmon.new) .v # => shark


Para contrastar la respuesta de @ khelll, esto usa variables de instancia en los objetos de clase:

class Fish # an instance variable of this Class object @var = ''fish'' # the "getter" def self.v @var end # the "setter" def self.v=(a_fish) @var = a_fish end end class Trout < Fish self.v = ''trout'' end class Salmon < Fish self.v = ''salmon'' end p Trout.v # => "trout" p Salmon.v # => "salmon"

Editar: para dar a las instancias acceso de lectura a la variable de instancia de la clase:

class Fish def type_of_fish self.class.v end end p Trout.new.type_of_fish # => "trout" p Salmon.new.type_of_fish # => "salmon"


@var mencionado anteriormente se llama variable de instancia de clase , que es diferente de las variables de instancia ... lea la respuesta here para ver la diferencia.

De todos modos, este es el código Ruby equivalente:

class Fish def initialize @var = ''fish'' end def v @var end end class Trout < Fish def initialize @var = ''trout'' end end class Salmon < Fish def initialize @var = ''salmon'' end end puts Trout.new.v puts Salmon.new.v