了解Ruby继承

时间:2013-02-17 07:02:39

标签: ruby inheritance

我一直在阅读Well Grounded Rubyist,它提到了类如何继承其超类的实例方法,以便类的对象能够调用这些实例方法。这是一个例子:

class C
  def run_instance_method
    puts "This is an instance method."
  end
  def C.run_class_method
    puts "This is a class method."
  end
end

class D < C
end

根据我读过的内容,我们总是描述D类只继承C类的实例方法(在这种情况下,C :: run_class_method不会被D继承)。但是,运行上面的代码后,我注意到:

D.run_class_method # => "This is a class method."

我猜这是为什么会发生这种情况,如果这是正确的理解,请告诉我。如果存在类D的实例d并且您尝试运行d.run_instance_method,则该对象将搜索其方法查找路径,并查看该方法是在其单例类,其自己的类还是在其超类中定义的。由于run_instance_method是在C类中定义的,因此不会发生任何问题并将调用run_instance_method。对于类对象D(它是C和Object的子类),如果调用D.run_class_method,它将再次检查D类对象的方法查找路径。同样,Ruby会在类对象C中找到它。

这种推理准确吗?

2 个答案:

答案 0 :(得分:6)

类方法可以像实例方法一样继承和覆盖。如果父类定义了类方法,则子类继承该方法。也就是说,如果你的子类没有定义它自己的类方法,那么它继承它的超类。

作为建议:当使用显式接收器调用类方法时,应该避免依赖继承。始终通过定义它的类调用类方法。否则,依赖于您的代码的人很难找到定义类方法的父类。

回到你最初的假设:从子类调用类方法是可能的,因为类方法是eigenclass的实例方法。

class C
   # instance methods goes here
   class << self # open the eigenclass
   # class methods go here as instance methods of the eigenclass
   end
end

一般来说,将类方法定义为单独的单例方法而不显式打开特征类更为明确。

有关David Flanagan和Yukihiro Matsumoto的The Ruby Programming Language的清晰解释

答案 1 :(得分:2)

不是很确切。此处隐藏了另一个概念,称为metaclasseigenclass。类方法继承自eigenclass。有关它的更多信息,请参阅Ruby Hacking Guide。 (如果您不想全部阅读,只需在页面中搜索“类方法”。)