【问题标题】:Understanding Ruby Inheritance理解 Ruby 继承
【发布时间】:2013-02-17 07:02:39
【问题描述】:

我一直在阅读 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 类的实例方法(在这种情况下,D 不会继承 C::run_class_method)。但是,运行上面的代码后,我注意到:

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 中找到它。

这个推理准确吗?

【问题讨论】:

    标签: ruby inheritance


    【解决方案1】:

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

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

    回到您最初的假设:从子类调用类方法是可能的,因为类方法是 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

    【讨论】:

    • 感谢您的解释。如果我对这个解释不正确,你能纠正我吗:基本上,所有类方法都作为实例方法存在于它们的特征类中。如果类 D 继承自它的超类类 C,那么类 D 的特征类也隐式地继承自类 C 的特征类。正是由于这个原因,类对象D可以调用.run_class_method。这准确吗?
    • 没错!当 Ruby 评估方法调用表达式时,首先必须确定需要调用哪个方法。这就是所谓的method lookup:首先在self类中搜索方法定义,如果没有找到方法,则在class parent等中搜索直到链根。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2014-02-22
      • 1970-01-01
      • 2016-10-03
      • 2021-08-29
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多