我对此行为感到有些惊讶:
puts RUBY_VERSION # 2.4.1
class A
class << A
def my_method
puts self
end
end
end
class B < A ; end
puts A.singleton_methods.inspect # [:my_method]
puts B.singleton_methods.inspect # [:my_method]
puts B.my_method # B
puts A.my_method # A
在元编程Ruby 2(惊人的书BTW)中,Paolo Perrota说:
此外,单例类只有一个 实例(即其名称的来源),并且它们不能被继承
但是我们可以看到,该摘要中的类方法是B从A继承的。所以,有人可以解释一下它的工作原理吗?
这种行为意味着类是单例类的实例吗?
(老实说,我在写这本书之前解释了类方法的继承机制之前写过这篇文章。但是现在我理解了,我仍然认为这是一个有趣的话题)
答案 0 :(得分:2)
为什么类方法被继承?
puts RUBY_VERSION # 2.4.1
class A
class << A
def my_method
puts self
end
end
end
class B < A ; end
puts A.singleton_class == B.singleton_class.superclass # true
puts A == B.superclass # true
因此,在方法查找过程中,解释器转到B的单例类,在其中找不到方法my_method
,然后到A的单例类的那里。找到方法并执行。
但是我们应该承认,有两个类的继承链,它们在某种程度上处于竞争状态,这意味着必须首先遍历两个链中的一个。但是,哪一个是正常类之一或单例类中的哪一个?
好吧,如果您知道的更多,请告诉我,但是代码似乎可以告诉您:
puts RUBY_VERSION # 2.4.1
class Class
def my_method
puts "Those who seek for gold dig up much earth and find a little."
end
end
A = Class.new do
class << self
def my_method
puts self
end
end
end
class B < A ; end
Class.new.my_method # Those who seek for gold dig up much earth and find a little.
A.my_method # A
如果“普通”继承链优先于单例类的继承链,则A.my_method
的结果将与Class.new.my_method
相同,因为{{ 1}}是A
。如果删除Class
的单例方法,我们可以更清楚地看到它:
A
这种行为意味着类是单例类的实例吗?
我真的很想回答这个问题。但是我不太确定。难道不就意味着puts RUBY_VERSION # 2.4.1
class Class
def my_method
puts "Those who seek for gold dig up much earth and find a little."
end
end
A = Class.new do
# class << self
# def my_method
# puts self
# end
# end
end
class B < A ; end
Class.new.my_method # Those who seek for gold dig up much earth and find a little.
A.my_method # Those who seek for gold dig up much earth and find a little.
既是A
的实例又是它自己的单例类?双重继承!?
如果您了解得更多,请分享您的知识。这是一个非常有趣的话题:)