p 'a'.class.ancestors #=> [String, Comparable, Object, Kernel, BasicObject]
p String.class.ancestors #=> [Class, Module, Object, Kernel, BasicObject]
假设我在'a'上调用方法。它首先在String类中查找该对象,如果它在那里找不到它,它会在Comparable等中查找。
现在如果我在Class类上调用一个方法,它首先进入'Class',然后是'Module'等。
我不明白这是什么。为什么,当我在类似'a'的字符串实例上调用方法时,它不会查找'Class'中的方法?为什么'a'在其祖先列表中没有Class?
答案 0 :(得分:4)
由于'a'
不是class
,'a'
是string
,因此'a'
是class
{{的实例1}}。 String
是String
,因此它是class
class
的一个实例。
请记住这一点,Class
不和Class
的祖先。 String
是Class
的{{1}}。
当您在class
上调用方法时,ruby将尝试在String
的班级'a'
及其祖先中找到该方法,其中没有一个是'a'
通常情况下,当我们没有进行这样的抽象讨论时,您会说String
是Class
,或'a'
是String
。但这可能会导致当前背景下的混乱。
这是因为当前上下文中的String
关系可能意味着至少两个不同的事情。 Class
是is a
可能意味着对象x
是类Y
的实例,或者它可能意味着类x
继承自类{{1} }}。 (当然命名约定会建议Y
是一个对象而x
是一个类......但那些不够实用)
这种Y
关系的含糊不清是这里混乱的根源。因为在ruby中,所有类都是对象,类型为x
的对象。为了使整个情况既令人困惑又优雅,Y
也是一个对象! ...类型is a
!!
Class
因此,如果我们只是简单地谈谈Class
关系。 Class
是[7] pry(main)> 'a'.ancestors
NoMethodError: undefined method `ancestors' for "a":String
from (pry):7:in `__pry__'
[8] pry(main)> 'a'.class.ancestors
=> [String, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject]
[9] pry(main)> String.ancestors
=> [String, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject]
[10] pry(main)> String.class.ancestors
=> [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject]
[11] pry(main)> Class.ancestors
=> [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject]
[12] pry(main)> Class.class.ancestors
=> [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject]
,is a
是String
。但Class
不会从String
继承,而是Comparable
的实例。 String
不是Class
的实例,它继承自Class
。
现在是刷新继承自关系含义的好时机。 String
继承自Comparable
,这意味着Comparable
类型的所有对象也将继承类String
中的行为。由于Comparable
不会从String
继承,因此Comparable
类型的对象实例不会继承类String
中的任何行为。
回到“是一种”关系。 Class
是String
。现在这适用于两种关系。 Class
肯定继承自String
。但Object
,String
是一个实例,继承自Object。因此String也继承了类对象的行为。因此,当我们说Object
是Class
时,它可能意味着其中任何一个。虽然,如果我们谈论继承,我们可能会说“String
是String
”,这意味着类Object
的实例也是对象。虽然说“String
是一个Object
”(注意我放弃了文章“a”),但我们的意思是类String
本身就是一个对象。
我刚刚意识到了别的什么。还记得我们如何在Ruby中声明静态方法? Ruby on rails - Static method
你说......
String
如果您考虑一下,使用关键字Object
,我们就是指String
的对象性质。因此,当您稍后调用class X
def self.static_method
...
end
end
时,您将作为对象访问self
并引用与对象X
关联的实例方法。
希望我没有太多困扰你们。