При создании нескольких экземпляров объекта обрабатывает их как один и тот же объект в памяти - PullRequest
0 голосов
/ 25 сентября 2019

Итак, я пытаюсь использовать разные экземпляры одного и того же объекта.Я пришел из Java, и в Java вы можете просто использовать новое ключевое слово, и все готово.Я попробовал «Digit.new», и последний назначенный экземпляр этого объекта изменил все экземпляры этого объекта

Я пытался использовать ключевое слово «self», но это просто приводит к сбою моей программы.

n_one = Digit.new
n_two = Digit.new
n_three = Digit.new
n_four = Digit.new
am_pm = Digit.new

.
.
.
n_three.set_type 3

n_four.set_type 1

class Digit
  @@type = nil

  #This will determine what strings will be returned
  def set_type num
    @@type = num
  end
end

Ожидается, что тип n_three равен 3, а n_four равен 1. Но n_one, два, три и четыре равны 1.

1 Ответ

1 голос
/ 25 сентября 2019

Чтобы заполнить то, что Макс сказал в комментариях:

Символ @@ определяет переменную класса (вроде как в Java static).Переменные экземпляра идентифицируются знаком @.Все ваши объекты имеют одинаковое значение, потому что все они используют одну и ту же переменную класса.

set_type выглядит довольно неубедительно в большинстве случаев.Соглашение Java getFoo переводится как foo в Ruby и setFoo в foo=.Как и в

def foo
  @foo
end

def foo=(value)
  @foo = value
end

Кроме того, obj.foo = bar является синтаксическим сахаром для obj.foo=(bar) (вызывая функцию foo= с аргументом bar), поэтому код выглядит естественным (то есть использование установщика выглядит какприсваивание переменной).

attr_accessor :foo сделает оба эти метода за вас.attr_reader :foo и attr_writer :foo делают только метод получения или просто метод установки.Таким образом, ваш код может быть записан как

class Digit
  attr_writer :type
end

n_three = Digit.new
n_three.type = 3

, который идентичен

class Digit
  def type=(value)
    @type = value
  end
end

n_three = Digit.new
n_three.type=(3)

Конечно, если вы хотите читать n_three.type, вы будетеТакже необходимо определить геттер (или заменить attr_writer на attr_accessor в первом фрагменте).Обратите внимание, что вам также не нужно инициализировать @type в nil, так как это значение по умолчанию для неинициализированной переменной экземпляра.Но вы можете инициализировать его в методе initialize.

Java объединяет конструктор и инициализатор;в Ruby конструктор - ::new (метод класса, который мы обычно вызываем для создания новых объектов, которые вам почти никогда не нужно переопределять);и инициализатор #initialize (автоматически вызывается конструктором по умолчанию).Вы не можете инициализировать переменные экземпляра вне метода, как в Java.Итак, правильный способ инициализации переменной экземпляра был бы:

class Digit
  attr_writer :type

  def initialize(type)
    @type = type
  end
end

Если бы вы определили установщик, вы могли бы (и, вероятно, должны) использовать self.type = type вместо @type = type.

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