ruby中的子类可以访问实例变量吗?
我最近开始学习ruby。我想知道ruby中的实例变量到底是什么。我编写了一个小代码来了解实例变量是什么ruby中的子类可以访问实例变量吗?,ruby,Ruby,我最近开始学习ruby。我想知道ruby中的实例变量到底是什么。我编写了一个小代码来了解实例变量是什么 class Animal def animal_sound @sound = "roar" @sound + " "+"animal" end end class Human < Animal def human_sound @sound + " "+"human" end end human = Human
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
我知道实例变量只属于一个类,它的子类是独立的。但我的人类类是如何从动物类访问@sound的呢
我的人类课程是如何从动物课程中获取@声音的
没有。它访问了继承的方法(
Animal#Animal_sound
)。当您执行human.animal\u sound
时,它会将@sound
附加到当前的self
,即human
——实例(而不是human
,也不是animal
)@sound
不属于类;它属于实例(这就是为什么它被称为实例变量)。然后,human.human\u sound
再次从当前的self
读取@sound
,即human
(不是从human
,不是从Animal
)继承human
类。因此,Animal
类中的实例变量@sound
initiate可以在Human
类中访问
与继承父类属性的子类类似。您的示例代码没有很好地使用实例变量。。。它显示了实例方法的使用(以及从父类继承它们)。实例变量是仅可由该实例访问的变量 下面是一个例子:
class Animal
def animal_sound
@sound = "roar"
@sound + " "+"animal"
end
# This reader-method lets us see the value of the @eye_colour instance-variable
def eye_colour
"My eyes are: #{@eye_colour}"
end
# This writer-method lets us set the value of the @eye_colour instance variable
def eye_colour=(new_colour)
@eye_colour = new_colour
end
end
class Human < Animal
def human_sound
@sound + " "+"human"
end
# inherits the colour-methods from Animal
end
# when you create a new instance of human, you can give them an eye-colour
human = Human.new
human.eye_colour = "Green"
human.eye_colour # => "My eyes are: Green"
# if you create a new instance of human, you can give them a different eye colour
human2 = Human.new
human2.eye_colour = "Brown"
human2.eye_colour # => "My eyes are: Brown"
# but the first human is still the original colour -
# because the variable contains a value just for *that* instance.
# This is what it means to be an instance-variable
human.eye_colour # => "My eyes are: Green"
类动物
动物之声
@sound=“咆哮”
@声音+“”+“动物”
结束
#这个reader方法让我们看到@eye\u color实例变量的值
眼睛颜色
“我的眼睛是:{@eye\u color}”
结束
#这个writer方法允许我们设置@eye\u color实例变量的值
def眼睛颜色=(新颜色)
@眼睛颜色=新颜色
结束
结束
类人<动物
人声
@声音+“”+“人类”
结束
#继承了动物的色彩方法
结束
#当你创建一个新的人类实例时,你可以给他们一个眼睛颜色
人
人眼颜色=“绿色”
human.eye_color#=>“我的眼睛是绿色的”
#如果你创建了一个新的人类实例,你可以给他们一个不同的眼睛颜色
human2=Human.new
人眼2.眼睛颜色=“棕色”
人眼颜色“我的眼睛是棕色的”
#但是第一个人类仍然是原始的颜色-
#因为变量只包含*该*实例的值。
#这就是作为实例变量的含义
human.eye_color#=>“我的眼睛是绿色的”
Ruby实例由
human
可以解释为
...
|
Object { ... }
|
Animal { def animal_sound }
human -----> {@sound} |
<type> ----------------> Human { def human_sound }
。。。
|
对象{…}
|
动物{def Animal_sound}
人类------>{@sound}|
---------------->人类{def Human_sound}
human
实例上可用的任何实例方法(行为)都将对第1部分中的同一组实例变量进行操作。在您的示例中,这是{@sound}
实例变量本身并不是“继承”的,但由于它们存在于实例本身的上下文中,所以实例拥有的任何和所有方法都可以访问它们
将对象视为具有关联方法和实例变量的容器。您可以根据自己的需要添加、删除和更改这些方法,尽管通常在类定义中只添加和删除一次方法。因为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"
类动物
def初始化(名称=nil)
#定义定义其名称的本地实例变量
@name=name | |贝西'
结束
动物之声
#动物发出的默认噪音
“哞”
结束
def声音
#更个性化的音效
“%s转到%s”%[@name,动物音]
结束
结束
类人<动物
动物之声
#重写基于名称的默认行为
大小写(@name)
当‘布鲁斯’
#任何一个叫布鲁斯的人都会做一些不同的事情
“哟”
其他的
“罗尔”
结束
结束
结束
chucky=人类。新(“chucky”)
p.楚基声音
#=>“Chucky变为rawr”
bruce=人类。新建('bruce')
布鲁斯·桑德
#=>“布鲁斯去溜溜球”
在这里,@name
是在父类初始值设定项中分配的,但它绑定到实例本身,而实例本身实际上是Human
类型,因此它可以通过Human中的animal\u sound
等任何方法访问。请注意,这也是相反的,父类正在调用animal\u sound
,但最终使用的是子类版本,而不是父类版本,因为子类定义了不同的行为
这是面向对象编程的基石。人类类实际上与:
class Human
def animal_sound
@sound = "roar"
@sound + " " + "animal"
end
def human_sound
@sound + " " + "human"
end
end
对于您的新实例human=human.new
,当您调用animal\u sound
时,这将为您的特定实例human
定义@sound
因为@sound
是一个实例变量,所以人类可用的所有其他方法都可以使用它。也就是说,@sound
也可以在人声
中看到
请注意,如果在animal\u sound
之前调用human\u sound
,@sound
将返回nil
,这将导致错误。由于@sound
将在其他地方使用,因此在特殊的initialize
方法中定义它是合理的。这边@soundclass Human
def animal_sound
@sound = "roar"
@sound + " " + "animal"
end
def human_sound
@sound + " " + "human"
end
end
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"