转载收藏: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

 

猜你喜欢

转载自jy503160.iteye.com/blog/2148801