클래스 변수와 클래스 인스턴스 변수의 차이점은 무엇입니까?


답변:


151

클래스 변수 ( @@)는 클래스와 모든 하위 항목간에 공유됩니다. 클래스 인스턴스 변수 ( @)는 클래스의 자손이 공유하지 않습니다.


클래스 변수 ( @@)

클래스 변수가있는 Foo 클래스와 @@i읽기 및 쓰기를위한 접근자를 가집시다 @@i.

class Foo

  @@i = 1

  def self.i
    @@i
  end

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

end

그리고 파생 클래스 :

class Bar < Foo
end

Foo와 Bar는 다음과 같은 값을가집니다 @@i.

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

그리고 @@i하나에서 변경하면 두 가지 모두에서 변경됩니다.

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

클래스 인스턴스 변수 ( @)

@i읽기와 쓰기를위한 접근 자와 클래스 인스턴스 변수가있는 간단한 클래스를 만들어 봅시다 @i:

class Foo

  @i = 1

  def self.i
    @i
  end

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

end

그리고 파생 클래스 :

class Bar < Foo
end

Bar는에 대한 접근자를 상속하지만 자신을 @i상속하지는 않습니다 @i.

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

@iFoo에 영향을주지 않고 Bar를 설정할 수 있습니다 @i.

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

1
클래스 메서드를 사용하여 인스턴스 변수를 반환하는 이유는 무엇입니까? 이 상황에 자주 부딪 치나요?
sekmo

1
@sekmo이 예제의 접근 자는 클래스에 속하는 클래스 인스턴스 변수 또는 클래스 계층에 속하는 클래스 변수를 반환합니다 . 클래스의 인스턴스에 속하는 일반 인스턴스 변수 를 반환하지 않습니다 . "인스턴스 변수", "클래스 인스턴스 변수"및 "클래스 변수"라는 용어는 상당히 혼란스럽지 않습니까?
Wayne Conrad

72

먼저 클래스도 인스턴스라는 것을 이해해야합니다. Class .

이를 이해하면 일반 (읽기 ​​: 비 클래스) 객체와 마찬가지로 클래스에 인스턴스 변수가 연결될 수 있음을 이해할 수 있습니다.

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

에서 인스턴스 변수 유의 Hello온 인스턴스 변수는 전혀 관계없는 별개이다 인스턴스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!"

반면에 클래스 변수 는 위의 두 가지 조합의 일종으로, Hello자체 및 해당 인스턴스뿐 아니라의 하위 클래스 및 해당 인스턴스에서 액세스 할 수 있습니다 Hello.

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

많은 사람들이 class variables위의 이상한 행동 때문에 피하라고 말하고 class instance variables대신 사용을 권장합니다 .


2
+1 슈퍼 설명! 이것은 Ruby를 처음 접하는 모든 프로그래머가 소화해야 할 내용입니다.
TomZ 2011

0

또한 클래스의 @@모든 인스턴스에서 클래스 변수 ( )에 액세스 할 수 있음을 추가하고 싶습니다.

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

그러나 클래스 인스턴스 변수 ( @)에 대해 동일한 작업을 수행 할 수 없습니다.

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

-1 : 이것은 올바르지 않습니다. 클래스 인스턴스 변수는 해당 클래스의 모든 인스턴스에서 액세스 할 수 있습니다 (접근자가있는 경우). 게다가, 귀하의 예제는 클래스 인스턴스 변수가 아닌 일반 인스턴스 변수를 보여줍니다. 클래스 인스턴스 변수는 메서드 외부에서 선언되며 일반 인스턴스 변수 및 클래스 변수와 근본적으로 다릅니다.
The Pellmeister

해당 클래스의 모든 인스턴스에서 클래스 인스턴스 변수에 액세스하려면 어떻게해야합니까?
Evan Ross

Wayne Conrad의 답변을 읽었습니까? 그것은 말 그대로 그것을 설명합니다. stackoverflow.com/a/3803089/439592
Pellmeister

같은 클래스 메서드에서 액세스 할 수 있다는 것을 알고 Foo.i있지만이 클래스의 모든 인스턴스에 대해 어떻게 똑같이 할 수 Foo.new.i있습니까?
에반 로스

사용하여 #class. 나는 개인적 #class으로 무엇이든 호출 할 때 사용법을 생각 하지만 self코드 냄새입니다. 한 단계 더 나아가 인스턴스 접근 자 ii=해당 위임을 구현할 수도 있습니다.#class 동등한 항목에 수도 있습니다 Foo.new.i. 이 경우 . 객체 멤버를 수정하고 있음을 암시하는 혼란스러운 인터페이스를 생성하므로 권장하지 않습니다.
The Pellmeister
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.