Иметь метод родительского класса доступ к константам подкласса

Например:

class Animal

 def make_noise
    print NOISE
 end

end

class Dog < Animal
    NOISE = "bark"
end

d = Dog.new
d.make_noise # I want this to print "bark" 

Как мне выполнить вышеуказанное? В настоящее время написано

uninitialized constant Animal::NOISE
25
задан Phrogz 26 January 2012 в 06:54
поделиться

2 ответа

Я думаю, что вы действительно не хотите постоянную; Я думаю, что вы хотите переменную экземпляра для класса:

class Animal
  @noise = "whaargarble"
  class << self
    attr_accessor :noise
  end
  def make_noise
    puts self.class.noise
  end
end

class Dog < Animal
  @noise = "bark"
end

a = Animal.new
d = Dog.new
a.make_noise  #=> "whaargarble"
d.make_noise  #=> "bark"
Dog.noise = "WOOF"
d.make_noise  #=> "WOOF"
a.make_noise  #=> "whaargarble"

Однако, если вы уверены, что хотите постоянную:

class Animal
  def make_noise
    puts self.class::NOISE
    # or self.class.const_get(:NOISE)
  end
end
27
ответ дан 28 November 2019 в 21:38
поделиться

Я думаю, у вас неправильная концепция. Классы в Ruby похожи на классы в Java, Smalltalk, C #, ... и все являются шаблонами для своих экземпляров. Таким образом, класс определяет структуру и поведение его экземпляров, а также части структуры и поведения экземпляров его подклассов , но не наоборот .

Так что прямой доступ из суперкласса к константе в подклассе вообще невозможен, и это хорошо. Смотрите ниже, как это исправить. Для ваших классов определены следующие вещи:

  • class Animal определяет метод make_noise.
  • экземпляры class Animal могут вызывать метод make_noise.
  • class Dog определяет константу NOISE с ее значением.
  • экземпляры Dog и сам класс Dog могут использовать константу NOISE.

Что невозможно:

  • Экземпляры Animal или сам класс Animal имеют доступ к константам класса Dog.

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

class Animal
  def make_noise
    print Dog::NOISE
  end
end

Но это плохой стиль, потому что теперь ваш суперкласс (который является абстракцией о Dog и других животных) теперь знает то, что принадлежит Dog.

Лучшим решением было бы:

  1. Определить абстрактный метод в классе Animal, который определяет, что должно быть определено make_noise. См. Ответ https://stackoverflow.com/a/6792499/41540 .
  2. Определяйте в ваших конкретных классах метод снова, но теперь со ссылкой на константу.
  3. [1 125]
0
ответ дан 28 November 2019 в 21:38
поделиться
Другие вопросы по тегам:

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