我一直在阅读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中找到它。
这种推理准确吗?
答案 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)
不是很确切。此处隐藏了另一个概念,称为metaclass
或eigenclass
。类方法继承自eigenclass。有关它的更多信息,请参阅Ruby Hacking Guide。 (如果您不想全部阅读,只需在页面中搜索“类方法”。)