Смешение достопри метод и метод 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 дает нам гибкость обеспечить значения для экземпляра переменных в любое время.