Dav*_*vid 22 ruby initialization accessor
我看到代码如下:
class Person
def initialize(name)
@name = name
end
end
Run Code Online (Sandbox Code Playgroud)
我明白这一点让我做这样的事情person = Person.new
,并用@name
在我的课像其他方法中的别处.然后,我看到代码如下:
class Person
attr_accessor :name
end
...
person = Person.new
person.name = "David"
Run Code Online (Sandbox Code Playgroud)
我只是对这两种方法网格感到茫然.有什么特别的用途def initialize(name)
?我想attr_accessor
允许我读写.这意味着它们是两种不同的方法.是?希望在澄清def initialize
和attr_accessor
他们如何网状.
Ser*_*sev 24
initialize
并且attr_accessor
彼此无关.attr_accessor :name
创建了几种方法:
def name
@name
end
def name=(val)
@name = val
end
Run Code Online (Sandbox Code Playgroud)
如果要在创建对象时设置名称,可以在初始化程序中执行此操作:
def initialize(name)
@name = name
# or
# self.name = name
end
Run Code Online (Sandbox Code Playgroud)
但你不必这样做.您可以在创建后稍后设置名称.
p = Person.new
p.name = "David"
puts p.name # >> "David"
Run Code Online (Sandbox Code Playgroud)
Aru*_*hit 15
这是您正在寻找的答案Classes and methods
.仔细阅读.
这是链接中的一个很好的文档:
类和方法
现在我们准备创建自己的Address类了.让我们开始吧.让我们从一个只包含"street"字段的地址开始.
这是你定义一个类的方法:
class Address
def initialize(street)
@street = street
end
end
Run Code Online (Sandbox Code Playgroud)
我们来看看:
class关键字定义了一个类.
通过在此类中定义方法,我们将其与此类关联.
initialize方法实际上是构造数据结构的方法.每个类都必须包含一个initialize方法.
@street是一个对象变量.类似于哈希的键.@符号将@street区分为对象变量.每次创建Address类的对象时,此对象都将包含@street变量.
让我们使用这个类来创建一个地址对象.
address = Addres.new("23 St George St.")
Run Code Online (Sandbox Code Playgroud)
而已.address现在是类Address的对象读取对象中的数据
假设我们想要读取地址对象中的数据.为此,我们需要编写一个返回此数据的方法:
class Address
def initialize(street)
@street = street
end
# Just return @street
def street
@street
end
end
Run Code Online (Sandbox Code Playgroud)
现在使用Address#street方法可以读取地址的街道.在irb:
>> address.street
=> "23 St George St."
Run Code Online (Sandbox Code Playgroud)
在外部可见的对象的属性称为属性.在这种情况下,street是一个属性.特别是,它是一个可读属性.因为这种属性很常见,所以Ruby通过attr_reader关键字为您提供了一个快捷方式:
class Address
attr_reader :street
def initialize(street)
@street = street
end
end
Run Code Online (Sandbox Code Playgroud)
更改对象中的数据
我们还可以定义一种方法来更改对象中的数据.
class Address
attr_reader :street
def initialize(street)
@street = street
end
def street=(street)
@street = street
end
end
Run Code Online (Sandbox Code Playgroud)
Ruby在使用street =方法时非常聪明:
`address.street = "45 Main St`."
Run Code Online (Sandbox Code Playgroud)
请注意,您可以在街道和=之间添加空格.现在我们可以更改地址数据,我们可以简化初始化方法,并将它简单地默认为空字符串"".
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."
Run Code Online (Sandbox Code Playgroud)
这似乎不是简化,但是当我们添加city,state和zip字段以及更多方法时,这将使类定义更简单一些.
现在,street也是一个可写属性.和以前一样,您可以使用attr_writer声明它:
class Address
attr_reader :street
attr_writer :street
def initialize
@street = ""
end
end
Run Code Online (Sandbox Code Playgroud)
访问数据
通常,您具有可读和可写属性的属性.Ruby允许你将这些与attr_accessor混为一谈.我想这些将被称为"可访问属性",但我从未见过它们被称为"可访问属性".
class Address
attr_accessor :street
def initialize
@street = ""
end
end
Run Code Online (Sandbox Code Playgroud)
有了这些知识,现在很容易定义整个地址簿结构.事实证明,attr_accessor和朋友都接受多个参数.
class Address
attr_accessor :street, :city, :state, :zip
def initialize
@street = @city = @state = @zip = ""
end
end
Run Code Online (Sandbox Code Playgroud)
我认为你认为initialize
是一个构造函数.确切地说,事实并非如此.默认构造函数是new
类的方法,initialize
由该方法调用.如果您没有定义initialize
,您仍然可以创建一个对象,new
因为initialize
它不是构造函数本身.在这种情况下,默认initialize
不执行任何操作.如果你确实定义了initialize
,那么在创建对象后立即调用它.
声明@foo = ...
和attr_accessor :foo
不同.前者为实例变量赋值@foo
,而后者允许您@foo
通过方法foo
和foo=
.如果没有后者,您仍然可以@foo
通过直接描述来访问.