Ruby - читать значение переменной в другом классе? - PullRequest
0 голосов
/ 16 ноября 2010

У меня есть что-то вроде следующего

class A 

  def initialize
    @var = 0
  end

  def dosomething
      @var+=1
  end

end

class B < A

 def initialize
   super
 end
 def func
    puts @var
 end
end

Проблема в том, когда я звоню

 a = A.new
 a.dosomething
 b = B.new

значение, которое @var возвращает, равно 0 как мне изменить свой код, чтобы он возвращал "новое" значение var (1)?

Ответы [ 5 ]

4 голосов
/ 16 ноября 2010

Быстрый ответ, если вы действительно понимаете Классы, Наследование и Объекты: замените @var (переменная экземпляра, и поэтому отличается в a и b) на @@var (переменная класса, и, следовательно, во всех случаях class A).

В противном случае ваш вопрос показывает, что у вас есть фундаментальное неправильное понимание того, что происходит с классами, объектами и наследованием.

Ваш код выполняет следующие действия:

  • Определяет класс с именем A. По сути, это план, из которого вы можете создавать объекты.
    • Объявляет, что при создании объекта типа A этому объекту должна быть предоставлена ​​собственная личная копия атрибута с именем var, для которого установлено значение 0.
    • Объявляет, что объектам типа A можно задать dosomething, что увеличивает значение var этого объекта на 1.
  • Определяет класс с именем B, который является частным случаем A

Следовательно, во втором фрагменте вы создаете объект a, который является A. Он имеет свой собственный атрибут с именем var, который устанавливается в 0, а затем увеличивается. Затем вы создаете b, который является B (и, следовательно, также A). b имеет свой собственный атрибут с именем var, отдельно от a 'var, для которого установлено значение 0.

2 голосов
/ 16 ноября 2010

Переменные типа @var называются переменными экземпляра , потому что они уникальны для каждого экземпляра класса.Вы создали два отдельных экземпляра, a и b, и у них есть свои собственные переменные экземпляра.

Вы можете использовать переменные класса , если хотите видеть их в своем подклассе:

class A  
  @@var = 0 
  def dosomething 
    @@var += 1 
  end 
end 

class B < A 
 def func 
    puts @@var 
 end 
end 

Вы также можете использовать методы доступа уровня класса:

class A  
  class << self
    attr_accessor :var
    def dosomething(n) 
      self.var = n 
    end
  end 
end 

class B < A 
 def func 
    puts A.var 
 end 
end 

irb(main):031:0> A.dosomething(5)
=> 5
irb(main):032:0> b = B.new
=> #<B:0x2b349d>
irb(main):033:0> b.func
5

Обратите внимание, что наследование не требуется для этой работы.

1 голос
/ 16 ноября 2010

Вы можете использовать переменные класса:

class A 
  @@var = 0
  def dosomething
    @@var += 1
  end
end

class B < A
 def func
    puts @@var
 end
end

a = A.new
a.dosomething
a.dosomething
b = B.new
b.func # => 2
1 голос
/ 16 ноября 2010

@var является переменной экземпляра , каждый экземпляр этого класса имеет свое значение этой переменной.Поэтому верно, что b возвращает 0, поскольку это другой экземпляр по сравнению с a.

. Чтобы обновить значение в b, используйте:

b = B.new
b.dosomething

Здесь - дополнительная информация о переменных экземпляра.

Или , если вы хотите переменную класса (то есть переменную, которая такая же в все экземпляры этого класса), используйте @@var.Тогда ваш приведенный пример сработает.

Здесь - дополнительная информация о переменных класса.

Какое решение вам нужно, зависит от вашего приложения.

0 голосов
/ 16 ноября 2010

Вам нужно использовать переменные класса, а не переменные экземпляра.Попробуйте что-то вроде этого:

class A

  @@var = 0

  def dosomething
      @@var+=1
  end
end

class B < A

 def func
    puts @@var
 end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...