在ruby中继承期间类方法查找如何工作?

时间:2017-12-28 08:27:57

标签: ruby

在Ruby中,类方法在接收器对象的单例类中查找。

class Child
  class << self
    def hello
      p 'hello'
    end
  end
end

我明白这是如何运作的;它来自Child的单身人士课程。

p Child.singleton_class.instance_methods(false)
>> [:hello]

但是当我们做这种情况下的继承时,

class Parent
  class << self
    def hello
      p 'hello'
    end
  end
end

class Child < Parent
end

我不明白Child.hello是如何运作的。类Child不与其单例类链接,而是直接链接到Class对象。

p Child.singleton_class.instance_methods(false)
>> []

然而,Parent类与其单例类相关联,其中定义了hello

p Parent.singleton_class.instance_methods(false)
>>[:hello]

但我不明白调用Child.hello如何查找Parent的单例类中的方法。

这就是我看到连接对象的方式:

p Child.class.ancestors   
>> [Class, Module, Object, Kernel, BasicObject]

3 个答案:

答案 0 :(得分:2)

好的,既然这个问题被投了赞成票,我会在这里留下正确的答案。

double的定义是因为Child.hello的本征类派生自Child的本征类:

Parent

这个本征类的整个祖先链将是:

▶ Child.singleton_class.superclass
#⇒ #<Class:Parent>

前四个祖先是▶ Child.singleton_class.ancestors #⇒ [#<Class:Child>, #<Class:Parent>, # #<Class:Object>, #<Class:BasicObject>, # Class, Module, Object, Kernel, BasicObject] 链中各个类的特征类。这就是如何在ruby中构建/派生特征类,使Child.ancestors之类的调用可用。

虽然Child.hello方法没有直接显示:hello方法,因为它不是在Child.singleton_class.instance_methods(false)的本征类上定义的,它仍然存在,感谢Child的eigenclass:

Parent

答案 1 :(得分:-3)

在调用Child.class.ancestors之后,输出将显示类形式的祖先,其中Child是实例化的。是的,它可能看起来很奇怪而且令人困惑,但ChildClass类的实例。

如果你看一下在Ruby中声明类的另一种方式,它可能会变得更加清晰:

Child = Class.new { ... }

我猜这是你困惑的根源。你在错误的班级里寻找祖先。

如果你想看Child的祖先:

Child.ancestors
=> [Parent, Object, Kernel, BasicObject]

or

Child.new.class.ancestors
=> [Parent, Object, Kernel, BasicObject]

我相信在指出之后,.hello方法的查找对你来说变得清晰了。

答案 2 :(得分:-5)

Ruby不仅在单例类中查找方法。

以下是Ruby中继承和方法查找的入门知识:https://gist.github.com/damien-roche/351bf4e7991449714533