转自:http://www.cnblogs.com/IAmBetter/archive/2013/03/16/2963680.html
1.先看私有方法能否被继承
class
A
@@name
=
"Anleb"
def
ask
puts
@@name
end
private
:ask
end
a=
A
.
new
#a.ask
a.send(
:ask
)
class
B
<
A
end
b=
B
.
new
#b.ask
b.send(
:ask
)
|
结论:对于private方法,是被继承的,类变量(类似于静态变量,属于所有实例),也是可以被继承的。
2.看类的方法能否被继承
题外话:private影响谁?
class
A
private
def
self
.ask
puts
"class method1"
end
class
<<
self
def
play
puts
"class method2"
end
end
def
tell
puts
"instance methods"
end
end
A
.ask
A
.send(
:ask
)
A
.play
A
.send(
:play
)
a=
A
.
new
#a.tell
a.send(
:tell
)
|
结论:可以看到Private只影响实例方法,对类的方法没有影响,要想设定类的private方法,必须在类的单件类中设置。如下
class
<<
self
private
def
play
puts
"class method2"
end
end
|
进入正题,类的方法是否能继承
class
A
private
def
self
.ask
puts
"class method1"
end
class
<<
self
private
def
play
puts
"class method2"
end
end
def
tell
puts
"instance methods"
end
end
class
B
<
A
end
B
.ask
B
.send(
:play
)
|
结论:类的方法也是能继承的,如果看过元编程应该知道B的祖先链:B-A-A的单件类-Object-Kernel-BaseObject
3.类本身的实例变量是否能继承
class
A
@name
=
"Anleb"
class
<<
self
attr_accessor
:name
end
end
p
A
.name
class
B
<
A
end
p
B
.name
输出:
Anleb
nil
|
结论:说明类的实例变量是不继承的,注意,这里要区别于 类的对象的实例变量。
根据元编程的思路,就是:
对象包含:
对象对类的引用(指针)
对象的实例变量
对象的object_id
对象的状态tainted和frozen状态
类包含:
实例的方法
类变量
因为对象的实例变量是存在于对象中的,所有其他的对象无法从类中获得这个实例变量。
4.super
class
A
attr_accessor
:ob_name
def
initialize
@ob_name
=
"Anleb"
end
end
p
A
.
new
.ob_name
class
B
<
A
attr_accessor
:ob_id
def
initialize
@ob_id
=
1
end
end
p
B
.
new
.ob_name
输出:
Anleb
nil
#这里是Nil,是因为继承了attr_accessor生成的魔法方法
|
说明:这里不要误解了,都说是覆盖了父类A的initialize方法,其实不是的,因为对象调用方法的模式是:先向右-找到自己的类,然后再向上查找自己的祖先类。
这里没有调用父类A的初始化方法,是因为,先找到了自己类B的初始化方法。
如果也继承父类的同名方法呢?利用super
class
A
attr_accessor
:ob_name
def
initialize
@ob_name
=
"Anleb"
end
def
ask
puts
"A methods"
end
end
p
A
.
new
.ob_name
class
B
<
A
attr_accessor
:ob_id
def
initialize
@ob_id
=
1
super
end
def
ask
puts
"B methods"
super
end
end
p
B
.
new
.ob_name
B
.
new
.ask
输出:
"Anleb"
"Anleb"
B
methods
A
methods
|