Question

Quelqu'un peut-il me dire la différence entre les variables de classe et les variables d'instance de classe?

Était-ce utile?

La solution

Une variable de classe (@@) est partagée entre la classe et l'ensemble de ses descendants. Une variable d'instance de classe (@) n'est pas partagée par les descendants de la classe.


variable de classe (@@)

Ayons un Foo classe avec une @@i variable de classe, et accesseurs pour la lecture et l'écriture @@i:

class Foo

  @@i = 1

  def self.i
    @@i
  end

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

end

Et une classe dérivée:

class Bar < Foo
end

On voit que Foo et Bar ont la même valeur pour @@i:

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

Et changer @@i dans un il change à la fois:

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

variable d'instance de classe (@)

Faisons une classe simple avec un @i d'instance de classe variable et accesseurs pour la lecture et l'écriture @i:

class Foo

  @i = 1

  def self.i
    @i
  end

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

end

Et une classe dérivée:

class Bar < Foo
end

Nous voyons bien que Bar hérite des accesseurs pour @i, il ne hérite pas @i lui-même:

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

Nous pouvons définir la @i Bar sans affecter @i Foo:

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

Autres conseils

D'abord, vous devez comprendre que les classes sont des instances trop -. Instances de la classe Class

Une fois que vous comprenez cela, vous pouvez comprendre qu'une classe peut avoir des variables d'instance qui y sont associés comme un régulier (lire: non-classe). L'objet peut

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

Notez qu'une variable d'instance sur Hello est sans aucun rapport avec et distincte d'une variable d'instance sur une instance 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!"

Variable classe d'autre part est une sorte de combinaison des deux ci-dessus, accessible sur Hello lui-même et ses instances, ainsi que sur les sous-classes de Hello et leurs instances:

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

Beaucoup de gens disent d'éviter class variables à cause du comportement étrange ci-dessus, et de recommander l'utilisation de class instance variables à la place.

Je veux aussi ajouter que vous pouvez accéder à la variable de classe (@@) de toute instance de la classe

class Foo
  def set_name
    @@name = 'Nik'
  end

  def get_name
    @@name
  end
end


a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => Nik

Mais vous ne pouvez pas faire la même chose pour la variable d'instance de classe (@)

class Foo
  def set_name
    @name = 'Nik'
  end

  def get_name
    @name
  end
end


a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => nil
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top