Переменная экземпляра родительского класса доступа

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

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 экземпляра родителя в дочернем классе? Или это - просто плохой дизайн иерархии?

5
задан Andrew Grimm 28 September 2011 в 00:03
поделиться

3 ответа

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

Есть несколько вещей, которые я отметил в вашем коде:

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

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

8
ответ дан 18 December 2019 в 14:42
поделиться

По какой причине вы хотите, чтобы 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
2
ответ дан 18 December 2019 в 14:42
поделиться

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

3
ответ дан 18 December 2019 в 14:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: