了解Ruby继承

wmo*_*ock 6 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
Run Code Online (Sandbox Code Playgroud)

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

D.run_class_method # => "This is a class method."
Run Code Online (Sandbox Code Playgroud)

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

这种推理准确吗?

End*_*imo 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
Run Code Online (Sandbox Code Playgroud)

通常,将类方法定义为单独的单例方法而不显式打开特征类更清楚.

有关清晰的解释,请阅读David Flanagan和Yukihiro Matsumoto 的Ruby Programming Language