Смешение достопри метод и метод initialize в одном классе

Я вижу следующий код:

class Person
  def initialize(name)
    @name = name
  end
end

Я понимаю, что это позволяет мне делать такие вещи, как person = Person.new и использовать @name в другом месте моего класса, как и другие методы. Затем я увидел код, подобный:

class Person
  attr_accessor :name
end

...

person = Person.new
person.name = "David"

Я просто в недоумении с этими двумя методами сетки. Каковы конкретные применения def initialize(name)? Я полагаю attr_accessor позволяет мне читать и писать. Это означает, что это два отдельных метода. Да? Хочу разъяснений на def initialize и attr_accessor и как они сетку.

4 ответов


initialize и attr_accessor не имеют ничего общего друг с другом. attr_accessor :name создает несколько методов:

def name
  @name
end

def name=(val)
  @name = val
end

если вы хотите установить имя при создании объекта, вы можете сделать это в инициализатор:

def initialize(name)
  @name = name
  # or
  # self.name = name
end

но вы не должны этого делать. Вы можете установить имя позже, после создания.

p = Person.new
p.name = "David"
puts p.name # >> "David"

вот ответ, который вы ищете Classes and methods. Прочтите внимательно.

вот хорошая документация по ссылке:

классы и методы

теперь мы готовы создать свой собственный класс адресов. Начнем с простого. Начнем с адреса, который содержит только поле "улица".

вот как вы определяете класс:

class Address
    def initialize(street)  
        @street = street 
    end
end

давайте это:

  • ключевое слово class определяет класс.

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

  • метод initialize-это то, что фактически создает структуру данных. Каждый класс должен содержать метод initialize.

@street является переменной объекта. Подобно ключам хэша. Знак @ отличает @street как объект переменная. Каждый раз, когда вы создаете объект Адреса класса, этот объект будет содержать переменную @street.

давайте использовать этот класс для создания объекта адреса.

address = Addres.new("23 St George St.")  

вот и все. адрес объекта класса address Чтение данных в объекте

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

class Address
    def initialize(street)   
        @street = street 
    end

    # Just return @street
    def street
        @street
    end
end

теперь адрес метода#street позволяет прочитать улицу адреса. В ирб:

>> address.street 
=> "23 St George St."

свойство объекта, которое видно снаружи, называется атрибутом. В этом случае street is является атрибутом. В частности, это читаемый атрибут. Поскольку этот атрибут очень распространен, Ruby предлагает вам ярлык через ключевое слово attr_reader:

class Address
    attr_reader :street
    def initialize(street)   
        @street = street 
    end
end

изменение данных в объекте

мы также можем определить метод изменения данные в объекте.

class Address
    attr_reader :street
    def initialize(street)  
        @street = street 
    end
    def street=(street)
        @street = street
    end
end

Ruby довольно умен в своем использовании метода street=:

`address.street = "45 Main St`."

обратите внимание, что вы можете поставить пробелы betten street и =. Теперь, когда мы можем изменить адресные данные, мы можем упростить метод initialize, и он просто по умолчанию улице с пустой строкой "".

class Address
    attr_reader :street
    def initialize
        @street = ""
    end
    def street=(street)
        @street = street  
    end
end

address = Address.new
address.street = "23 St George St."

это не может показаться большим упрощением, но когда мы добавим поля city, state и zip и другие методы, это сделает определение класса немного проще.

сейчас, на улице тоже атрибут writable. Как и раньше, вы можете объявить его таковым с помощью attr_writer:

class Address
    attr_reader :street
    attr_writer :street  
    def initialize
        @street = ""
    end
end

доступ к данным

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

class Address
    attr_accessor :street  
    def initialize
        @street = ""
    end
end

С этими знаниями теперь легко определить всю структуру адресной книги. Как оказалось, attr_accessor и друзья принимают несколько аргументов.

class Address
    attr_accessor :street, :city, :state, :zip  
    def initialize
        @street = @city = @state = @zip = ""
    end
end

Я думаю, что вы считаете initialize как конструктор. Если быть точным, это не так. Конструктор по умолчанию -new метод в классе и initialize вызывается этот метод. Если вы не определяете initialize, вы все еще можете создать объект с new, потому что initialize не является самим конструктором. В этом случае значение по умолчанию initialize ничего не делает. Если вы определяете initialize, то вызывается сразу после создания объекта.

заявление @foo = ... и attr_accessor :foo несколько отличающийся. Первый присваивает значение переменной экземпляра @foo, в то время как последний позволяет получить доступ @foo С помощью методов foo и foo=. Без последнего, вы все еще можете получить доступ @foo непосредственно описывая так.


В отличие от C++, переменные экземпляра Java в Ruby являются частная по умолчанию (частично, поскольку они могут быть доступны с помощью a.instance_variable_get: @x)

например:

  class Dda
    def initialize task
        @task = task
        @done = false
    end
  end
item = Dda.new "Jogging" # This would call the initializer and task = Jogging would
be set for item
item.task # would give error as their is no function named task to access the instance
variable.

хотя мы установили значение item, но мы не сможем ничего с ним сделать, поскольку переменные instace являются частными в ruby. код для геттера:

def task
  @task
end
#for getter
def task=task
   @task = task
end

использование геттера обеспечит этот элемент.задача возвращает значение И используя setter дает нам гибкость обеспечить значения для экземпляра переменных в любое время.