Доступ к переменной экземпляра родительского класса - PullRequest
5 голосов
/ 20 мая 2010

Как это может работать?

class A
  attr_accessor :name

  def initialize params
    @name = params[:name]
    @collection << B.new 
  end
end

class B < A
  def initialize
    @my_name = lookup_something(<parent.name>)
  end
end

По сути, мне нужно значение из родительского класса, чтобы использовать его при поиске дочернего класса, но я не хочу передавать его явно, если есть лучший способ. Является ли экземпляр var родительского полностью недоступным в дочернем классе? Или это просто плохой иерархический дизайн?

Ответы [ 3 ]

8 голосов
/ 20 мая 2010

Я действительно не знаю, что вы пытаетесь сделать здесь - весь код, который вы разместили, работает с instance переменными. Переменные экземпляра для каждого объекта, а не для класса, поэтому я не знаю, что вы имеете в виду, когда говорите «Мне нужно значение из родительского класса».

В вашем коде я отмечу несколько вещей:

  • Базовые классы не должны никогда знать о подклассах. Поэтому создание B объектов в A#initialize не очень хорошая вещь, потому что база использует подкласс.
  • Вы перезаписываете класс B#initialize совершенно другим поведением, чем A#initialize. Вы даже изменили список параметров. Не очень хорошая вещь. Объект подкласса должен вести себя так же, как объект его суперкласса.
  • Когда вы вызываете B.new('myname'), переменная @name никогда не назначается, потому что метод A#initialize никогда не вызывается. Вам нужно будет либо позвонить super(:name => name) (для запуска суперкласса initialize), либо вы должны назначить @name непосредственно в B#initialize
  • После определения @name все ваши методы экземпляра могут использовать его значение. Включая те, которые определены в родительском / суперклассе.

Позвольте мне сказать, что я не совсем уверен, почему вы используете наследование здесь, у меня такое ощущение, что это не то, что вы хотите. Если у вас есть два класса для двух разных вещей, никогда не должно быть связанным с наследованием. Если вы хотите повторно использовать код, взгляните на функцию микширования в Ruby или составьте ваши сложные объекты из нескольких «меньших» объектов, поведение которых вы хотите использовать повторно.

3 голосов
/ 22 мая 2010

У Джона Нунемейкера есть хорошая статья на эту тему.

2 голосов
/ 20 мая 2010

По какой причине вы хотите B наследовать от A? Если у вас нет другой причины, правильный способ создать это - просто взять имя в качестве параметра для конструктора B и отказаться от наследования.

class A
  attr_accessor :name

  def initialize params
    @name = params[:name]
    @collection << B.new(@name)
  end
end

class B
  def initialize name
    @my_name = lookup_something(@name)
  end
end
...