当前位置: 代码迷 >> Ruby/Rails >> 转载归藏:ruby的继承
  详细解决方案

转载归藏:ruby的继承

热度:119   发布时间:2016-04-29 02:19:55.0
转载收藏:ruby的继承

转自: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

?