我最近开始学习红宝石。我想知道ruby中究竟是什么实例变量。我写了一个小代码来了解实例变量是什么。
class Animal
def animal_sound
@sound = "roar"
@sound + " "+"animal"
end
end
class Human < Animal
def human_sound
@sound + " "+"human"
end
end
human = Human.new
p human.animal_sound
p human.human_sound
输出:
"roar animal"
"roar human"
我知道实例变量只属于一个类,它的子类是分开的。但是我的人类是如何从动物类中访问@sound的呢?
答案 0 :(得分:3)
我的人类是如何从动物类中获取@sound的?
它没有。它访问了继承的方法(Animal#animal_sound
)。完成human.animal_sound
后,它会将@sound
附加到当前self
,即human
- 实例(不是Human
,而不是Animal
}})。 @sound
不属于班级;它属于实例(这就是它被称为实例变量的原因)。然后,human.human_sound
再次从当前@sound
读取self
,即human
(不是来自Human
,而不是来自Animal
)。
答案 1 :(得分:2)
Ruby实例由
组成在您的示例中,实例human
可以解释为
...
|
Object { ... }
|
Animal { def animal_sound }
human -----> {@sound} |
<type> ----------------> Human { def human_sound }
human
实例上可用的任何实例方法(行为)都将在第1部分中的同一组实例变量上运行。在您的示例中,这是{@sound}
。
答案 2 :(得分:2)
实例变量不是&#34;&#34;继承&#34;本身,但由于它们存在于实例本身的上下文中,因此可以通过实例具有的任何和所有方法来访问它们。
将对象视为具有关联方法和实例变量的容器。您可以根据需要添加,删除和更改这些,但通常只在类定义中添加和删除方法一次。只是因为Ruby高度动态,你可以随时随地做到这一点。
例如,这是一个重写的演示:
class Animal
def initialize(name = nil)
# Define a local instance variable that defines their name
@name = name || 'Betsy'
end
def animal_sound
# Default noise an animal makes
'moo'
end
def sound
# A more personalized sound effect
'%s goes %s' % [ @name, animal_sound ]
end
end
class Human < Animal
def animal_sound
# Override the default behaviour based on name
case (@name)
when 'Bruce'
# Where anyone named Bruce does something different
'yo'
else
'rawr'
end
end
end
chucky = Human.new('Chucky')
p chucky.sound
# => "Chucky goes rawr"
bruce = Human.new('Bruce')
p bruce.sound
# => "Bruce goes yo"
此处@name
在父类初始化程序中分配,但它绑定到实例本身,实际上是Human
类型,因此任何方法都可以访问它比如人类中的animal_sound
。请注意,这也是相反的,父类正在调用animal_sound
,但最终使用的是子类版本,而不是父类,因为子类定义了不同的行为。
这是面向对象编程的基石。
答案 3 :(得分:1)
您的示例代码没有很好地使用实例变量...它显示了实例方法的使用(以及从父类继承它们)。实例变量是只能访问该实例的变量。
以下是一个例子:
/home/mona/devstack/
答案 4 :(得分:0)
Human
类继承自Animal
类。因此,在@sound
类中启动的实例变量Animal
可以在Human
类中访问。
与继承父类属性的子类一样。
答案 5 :(得分:0)
人类实际上与以下相同:
class Human
def animal_sound
@sound = "roar"
@sound + " " + "animal"
end
def human_sound
@sound + " " + "human"
end
end
对于新实例human = Human.new
,当您致电animal_sound
时,会为您的特定实例@sound
定义human
。
因为@sound
是一个实例变量,所以human
可用的所有其他方法都可以使用它。也就是说,@sound
也可以在human_sound
中看到。
请注意,如果您在human_sound
之前致电animal_sound
,@sound
将返回nil
,这将导致错误。由于@sound
将在其他地方使用,因此在特殊的initialize
方法中定义它是合理的。这种方式@sound
自动定义为为每个新实例指定的。
现在,您调用animal_sound
和human_sound
的顺序无关紧要。
class Human
def initialize
@sound = "roar"
end
def animal_sound
@sound + " " + "animal"
end
def human_sound
@sound + " " + "human"
end
end
human = Human.new
human.human_sound #=> "roar human"
human.animal_sound #=> "roar animal"
答案 6 :(得分:0)
我知道实例变量只属于一个类
没有。实例变量属于对象(也称为实例)。这就是为什么他们被称为实例变量的原因。
但我的人类是如何从动物类中获取@sound的呢?
不是。实例变量属于human
。