Project1
标题: 我想问一下@实变量是什么意思? [打印本页]
作者: 欧买歌 时间: 2014-12-30 22:01
标题: 我想问一下@实变量是什么意思?
F1教程里的看不懂,说什么对象什么什么的
能不能举一个简单的例子(要脚本新手能看得懂的)。
作者: zeldafd 时间: 2014-12-30 22:30
本帖最后由 zeldafd 于 2014-12-30 22:33 编辑
@是類變量, 是指可於一個類之內使用的變量- class ABC
- def initialize
- @text = "abc"
- end
- def get_text
- return @text #可以在這裡叫上面那個已定義的類變量
- end
- end
复制代码 但是, 類變量在沒有使用attr_accessor、attr_reader或attr_write時, 則不能夠於外面被讀取或寫入
(其實它就是一個私有的變量, 在定義了GETTER和SETTER就能夠好好的讀取和寫入了
- def initialize(test)
- @test = test
- end
- def test #等同使用attr_reader, 即是getter, 或隨便叫作讀取器吧
- return @test;
- end
- def test=(test) #等同使用attr_writer, 即是setter, 或隨便叫作寫入器吧
- @test = test;
- end
复制代码 )
簡言之就是一個類的變量...(被揍
好吧, 類變量在使用了attr_accessor後就能以這樣的方式被其他類讀取
- class A
- attr_accessor :test
- def initialize
- @test = "test"
- end
- end
- $A = A.new
- $A.test
- #應該是這樣吧, 我也好久沒用RUBY了=,=
复制代码 此時test就變成了A的一個屬性一樣了,
以個人性化點的例子:
- class Person
- attr_accessor :name
- attr_accessor :gender
- attr_accessor :age
-
- def initialize
- @name = "- NO NAME -"
- @gender = "?"
- @\age = 0 #不知為什麼會自動tag到人...所以加了個反鈄槓...
- end
- end
- $me = Person.new
- $me.name = "RedSuns S.H.Chan" #RedSuns是我的英文名
- $me.gender = "M" #這是男的意思, 不代表我是個M, 你明的
- $me.age = 17
- #這就是我的屬性了~
复制代码 當你不想這個屬性被外界的類修改, 但又想被人讀取, 就使用attr_reader好了
但又只想被人寫入, 不想被外界知道實際的值就用上attr_writer吧(用於些接受資料和處理的類, 等遲點知道什麼叫MVC你就會明白了)
大概是這樣吧, 總覺得寫的很沒條理==
希望LZ不會覺得太亂吧Orz
作者: test 时间: 2015-1-1 17:17
本帖最后由 test 于 2015-1-1 18:20 编辑
如果不是很懂脚本,至少要先把基本的语法看懂。
不然的话没办法理解的……
因为面向对象的东西都是很抽象的。
比如类、对象、属性、方法……
RGSS里面没有属性这个东西,都是靠方法来模拟属性的。
为了说明简单地说明实例是什么东西,你就暂且把“类”看成是用来创造“对象”的东西。
>可是对象又是什么东西呢?
假如你是神,你可以创造世间万物。
这时,你创造的任何一个东西,都是一个对象。
你就把东西看成是一个对象就好了。(东西=对象)
无论是路边的石头、天上的小鸟、地上的小草……都是对象。
>怎么创造对象(东西)呢?
你说你觉得这个世界太平静了,那么我们就来创造人吧。
创造人之前,我们需要一个造人的模型(类)。
我们要来想象一下,人是什么。还有,你想让人拥有什么东西。
你说你只想让人具有生命值(hp)就好了。于是人就是这个样子:
class People
def initialize()
@hp = 100;
end
end
class People
def initialize()
@hp = 100;
end
end
这时候,造人的模型就做好了。
其中,人的生命值(@hp)就是楼主所问的实(例)变量。
变量的意思楼主应该知道了吧?就是会改变的量……
>那么实例是什么意思呢?
上面,人物的样子我们已经想象好了(上面的代码就是一个类),这就是人物的模型。但人物的模型是创造人用的,模型不是人,创造出来之后才是人。
造人的模型有了,可是这时候我们还没有创造出人物。所以这时候人还不存在。
这就需要我们创造。
这里的“实例”(动词)你就当成是“创造“的意思。
下面我们创造一个人物。
在上面的代码下面,新开一行加入一句:
这样我们就创造了一个人(实例了一个人)。
这时候,我们可以把这个人叫做一个实例。
这里的“实例”(名词)你就当成是“创造出来的东西“的意思。
此时,这个人物被我们创造出来了,所以他就拥有了生命值(hp)这个实例变量。
抽象点来说,
东西(对象)创造(实例)之后才拥有的变量,叫做实例变量。
也就是说,不创造(实例)出来,这个实例变量就不存在。
很多东西可能我说得不是很准确,不知道楼主能理解其中的关系吗?
作者: chd114 时间: 2015-1-1 17:20
zeldafd 发表于 2014-12-30 05:30
@是類變量, 是指可於一個類之內使用的變量但是, 類變量在沒有使用attr_accessor、attr_reader或attr_write ...
那么@@、@、$又有什么区别呢?
作者: 欧买歌 时间: 2015-1-1 18:02
chd114 发表于 2015-1-1 17:20
那么@@、@、$又有什么区别呢?
我也不知道
作者: test 时间: 2015-1-1 18:55
本帖最后由 test 于 2015-1-1 22:35 编辑
欧买歌 发表于 2015-1-1 18:02
我也不知道
请试着理解下面代码:
# 定义了一个全局变量$c,并使它的值等于333的函数。
def x()
$c = 333; #全局变量
end
# 测试用的类
class Test
#定义了一个类变量@@a,并使它的值等于111。
@@a = 111;
#创建实例的时候,会执行这个函数↓
def initialize(b)
@b = b; #定义了实例变量@b,并使它的值等于函数的参数b的值。
end
#输出类变量@@a的值的函数
def say_a()
p @@a;
end
#输出实例变量@b的值的函数
def say_b()
p @b;
end
#输出全局变量$c的值的函数
def say_c()
p $c;
end
#设置类变量@@a的值的函数
def set_a(v)
@@a = v;
end
#设置实例变量@b的值的函数
def set_b(v)
@b = v;
end
end
# 创建两个测试类的实例$t1和$t2。并分别使它们的实例变量@b的值为'222-1'和'222-2'。
$t1 = Test.new('222-1');
$t2 = Test.new('222-2');
# ●测试全局变量
# 在函数里使全局变量$c的值为333。
x();
# 使用$t1和$t2中的say_c函数输出全局变量$c的值。
$t1.say_c(); # 输出的值为333
$t2.say_c(); # 输出的值为333
$c = 333; #改变全局变量$c的值为33301
$t1.say_c(); # 输出的值为33301
$t2.say_c(); # 输出的值为33301
# ●测试实例变量
# 使用$t1和$t2中的say_b函数输出实例变量@b的值。
$t1.say_b(); # 输出的值为222-1
$t2.say_b(); # 输出的值为222-2
$t1.set_b(444); # 使用$1中的say_b函数,使实例变量@b的值变成444。
$t1.say_b(); # 输出的值为444
$t2.say_b(); # 输出的值为222-2
# ●测试类变量
# 使用$t1和$t2中的say_a函数输出类变量@@a的值。
$t1.say_a(); # 输出的值为333
$t2.say_a(); # 输出的值为333
$t1.set_a(555); # 使用$t1中的say_a函数,使类变量@@a的值变成555。
$t1.say_a(); # 输出的值为555
$t2.say_a(); # 输出的值为555
# ●它们的区别就在于它们的有效范围,在范围外使用这个变量脚本会出错。
# 全局变量从定义开始,在整个脚本里面任意的地方可以读取,改变它的值。
# 实例变量在实例化之后,各个实例之间它们的值不会相互影响。
# 类变量不实例化,在以这个类创建出来的每一个实例中共用。
# 定义了一个全局变量$c,并使它的值等于333的函数。
def x()
$c = 333; #全局变量
end
# 测试用的类
class Test
#定义了一个类变量@@a,并使它的值等于111。
@@a = 111;
#创建实例的时候,会执行这个函数↓
def initialize(b)
@b = b; #定义了实例变量@b,并使它的值等于函数的参数b的值。
end
#输出类变量@@a的值的函数
def say_a()
p @@a;
end
#输出实例变量@b的值的函数
def say_b()
p @b;
end
#输出全局变量$c的值的函数
def say_c()
p $c;
end
#设置类变量@@a的值的函数
def set_a(v)
@@a = v;
end
#设置实例变量@b的值的函数
def set_b(v)
@b = v;
end
end
# 创建两个测试类的实例$t1和$t2。并分别使它们的实例变量@b的值为'222-1'和'222-2'。
$t1 = Test.new('222-1');
$t2 = Test.new('222-2');
# ●测试全局变量
# 在函数里使全局变量$c的值为333。
x();
# 使用$t1和$t2中的say_c函数输出全局变量$c的值。
$t1.say_c(); # 输出的值为333
$t2.say_c(); # 输出的值为333
$c = 333; #改变全局变量$c的值为33301
$t1.say_c(); # 输出的值为33301
$t2.say_c(); # 输出的值为33301
# ●测试实例变量
# 使用$t1和$t2中的say_b函数输出实例变量@b的值。
$t1.say_b(); # 输出的值为222-1
$t2.say_b(); # 输出的值为222-2
$t1.set_b(444); # 使用$1中的say_b函数,使实例变量@b的值变成444。
$t1.say_b(); # 输出的值为444
$t2.say_b(); # 输出的值为222-2
# ●测试类变量
# 使用$t1和$t2中的say_a函数输出类变量@@a的值。
$t1.say_a(); # 输出的值为333
$t2.say_a(); # 输出的值为333
$t1.set_a(555); # 使用$t1中的say_a函数,使类变量@@a的值变成555。
$t1.say_a(); # 输出的值为555
$t2.say_a(); # 输出的值为555
# ●它们的区别就在于它们的有效范围,在范围外使用这个变量脚本会出错。
# 全局变量从定义开始,在整个脚本里面任意的地方可以读取,改变它的值。
# 实例变量在实例化之后,各个实例之间它们的值不会相互影响。
# 类变量不实例化,在以这个类创建出来的每一个实例中共用。
作者: taroxd 时间: 2015-1-1 20:27
本帖最后由 taroxd 于 2015-1-1 20:29 编辑
obj = Object.new
obj.instance_variable_set(:@ivar, obj)
p obj # => #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
p obj.instance_variable_get(:@ivar) # => #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
def obj.sell_moe
p @ivar
end
obj.sell_moe # => #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
obj.sell_moe.sell_moe.sell_moe
# =>
# #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
# #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
# #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
obj = Object.new
obj.instance_variable_set(:@ivar, obj)
p obj # => #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
p obj.instance_variable_get(:@ivar) # => #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
def obj.sell_moe
p @ivar
end
obj.sell_moe # => #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
obj.sell_moe.sell_moe.sell_moe
# =>
# #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
# #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
# #<Object:0x00000002cd5008 @ivar=#<Object:0x00000002cd5008 ...>>
匿了 {:8_462:}
作者: XYZ加农炮 时间: 2015-1-1 20:36
@被称为实例变量,每一个对象在被创建时继承了类里实例变量的初始值,对象与对象之间的实例变量是独立的。
作者: 欧买歌 时间: 2015-1-1 21:02
test 发表于 2015-1-1 18:55
请试着理解下面代码:
# 定义了一个全局变量$c,并使它的值等于333的函数。
那么_变量又是什么鬼?
作者: test 时间: 2015-1-1 22:13
本帖最后由 test 于 2015-1-1 22:31 编辑
欧买歌 发表于 2015-1-1 21:02
那么_变量又是什么鬼?
没注意看前面有个下划线...
作者: 寒冷魔王 时间: 2015-1-2 00:34
本帖最后由 寒冷魔王 于 2015-1-2 00:47 编辑
@实例变量 与 @@类变量 的作用域是不同的。实例变量是在类new(实例)的时候被创建,而类变量是该类作为Class类对象时的特征变量。
比如:- class C
- @[url=home.php?mod=space&uid=16629]@HELLO[/url] = "Hello"
- def initialize
- [url=home.php?mod=space&uid=16629]@HELLO[/url] = "Hi"
- end
- class << self
- def hello
- puts "There is in self.hello"
- puts "@[url=home.php?mod=space&uid=16629]@HELLO[/url] = #{@@hello}"
- puts "@hello = #{@hello}"
- end
- end
- def hello
- puts "There is in hello"
- puts "@@hello = #{@@hello}"
- puts "@hello = #{@hello}"
- end
- end
- C.hello
- C.new.hello
复制代码 另外在class<<self内也可以定义实例变量,但那又存在一个新的作用域。相当于类的类实例变量。(好复杂)
作者: taroxd 时间: 2015-1-2 07:44
本帖最后由 taroxd 于 2015-1-2 07:48 编辑
寒冷魔王 发表于 2015-1-2 00:34
@实例变量 与 @@类变量 的作用域是不同的。实例变量是在类new(实例)的时候被创建,而类变量是该类作为Class ...
实例变量并不一定是在 new 的时候创建的,反例见7L
要个更加典型的反例的话
module SceneManager
[url=home.php?mod=space&uid=420706]@Scene[/url] = nil
@stack = nil
# ...
end
module SceneManager
[url=home.php?mod=space&uid=420706]@Scene[/url] = nil
@stack = nil
# ...
end
或者
module Cache
def self.load_bitmap
[url=home.php?mod=space&uid=341345]@Cache[/url] ||= {}
end
end
module Cache
def self.load_bitmap
[url=home.php?mod=space&uid=341345]@Cache[/url] ||= {}
end
end
class C
def some_attribute
@some_attribute ||= []
end
end
class C
def some_attribute
@some_attribute ||= []
end
end
类变量和实例变量的主要区别在于作用域不同。本类及其子类,还有本类及其子类的实例中都可以访问到。因为可能被子类随意修改所以不建议使用。
---
就我个人而言,我总是会把实例变量和 self 关联在一起,根据 self 判断当前访问的是哪个对象的实例变量。
类变量嘛……从来不用,总是用类实例变量或者常量代替。
作者: zeldafd 时间: 2015-1-2 08:59
欧买歌 发表于 2015-1-1 21:02
那么_变量又是什么鬼?
以_開頭的其實是一些人用寫類的私有變量時的寫法, 在不同的語言都有人這樣的表達.
其實寫出來給自己知道這是個私有的變量, 解析器是看不懂的.
而且個人也不太喜歡這種寫法, 所以結論是可以無視
欢迎光临 Project1 (https://rpg.blue/) |
Powered by Discuz! X3.1 |