Как объявить переменную 'stati c' в классе ruby? - PullRequest
1 голос
/ 28 января 2020

Я знаю PHP & Javascript, но я только начинаю изучать Ruby.

В настоящее время это работает:

  class Animal
    attr_accessor :name, :mammal
    def initialize(name)
      @name = name
    end
  end

  class Fish < Animal
    def initialize(name)
      super(name)
      @mammal = false
    end
  end

  class Cow < Animal
    def initialize(name)
      super(name)
      @mammal = true
    end
  end

  animals = [
    Fish.new('Moppy'),
    Cow.new('Marguerite'),
  ]

  animals.each do |animal|
    puts "Is #{animal.name} a mammal ? #{animal.mammal}"
  end

См. Переменную @mammal в подклассах?

Они являются переменными 'stati c', которые зависят не от экземпляра, а от самого класса (корова всегда будет млекопитающим, в то время как выигранный е sh) t)

Мне было интересно, объявлял ли я @mammal var в нужном месте. Инстинктивно, я бы предпочел сделать это

  class Cow < Animal
    @mammal = true
    def initialize(name)
      super(name)
    end
  end

, но тогда это не работает ... Может кто-нибудь сказать мне, если как вы должны справиться с этим с Ruby?

Спасибо!

Ответы [ 4 ]

3 голосов
/ 28 января 2020

Самое простое решение:

  class Fish < Animal
    def mammal
      false
    end
  end

  class Cow < Animal
    def mammal
      true
    end
  end

Лично я бы соблазнился сделать что-то вроде:

  class Animal
    attr_accessor :name

    def initialize(name)
      @name = name
    end

    def mammal
      false
    end
  end

  class Mammal < Animal
    def mammal
      true
    end
  end

  class Fish < Amimal
  end

  class Cow < Mammal
  end
1 голос
/ 28 января 2020

Если вы хотите использовать переменную всего класса, определите переменную экземпляра на уровне класса.

class Animal
    attr_accessor :name
    def initialize(name)
      @name = name
    end

    def self.mammal # class level
      @mammal
    end
  end

  class Fish < Animal
    @mammal = false # class level
  end

  class Cow < Animal
    @mammal = true # class level
  end

  [
    Fish.new('Moppy'),
    Cow.new('Marguerite'),
  ].each do |animal|
    puts "Is #{animal.name} a mammal ? #{animal.class.mammal}"
  end

Также можно использовать так называемые «переменные класса» @mammal, но они ведут себя странно при некоторые обстоятельства, поэтому переменная экземпляра на уровне класса будет лучше соответствовать вашим потребностям.

0 голосов
/ 28 января 2020

Для каждого подкласса @mammal одинаково для всех экземпляров и не предназначено для изменения. Следовательно, это должна быть константа или значение, возвращаемое методом класса. Первоначально я выбрал первое, но @tadman убедил в комментариях, что предпочтителен метод класса, в частности метод с именем, заканчивающимся знаком вопроса. Если интересно, см. Мой оригинальный ответ в истории редактирования.

class Animal
  attr_accessor :name
  def initialize(name)
    @name = name
  end
end

class Fish < Animal
  def initialize(name)
    super
  end
  def self.mammal?
    false
  end
end

class Cow < Animal
  def initialize(name)
    super
  end
  def self.mammal?
    true
  end
end

i = Fish.new('Moppy')
"#{i.name} is a mammal: #{i.class.mammal?}"
  #=> "Moppy is a mammal: false" 
i = Cow.new('Marguerite')
"#{i.name} is a mammal: #{i.class.mammal?}"
  #=> "Marguerite is a mammal: true" 
0 голосов
/ 28 января 2020

@var - это переменная экземпляра, а @@var - переменная класса (обе частные).

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

Большая разница между классами Переменные (@@) и переменные экземпляра класса (@ в области видимости класса) состоят в том, что первый является общим для всего дерева наследования , в то время как второй является частным для одного указанного c класса. Но учитывая, что ваша структура Mammal как класс, имеет больше смысла, чем любой.

См. Ruby переменная экземпляра класса и переменная класса для различных примеров.

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