类方法和单例方法是相同还是不同?这是一个例子。
class C
def self.classmethod
puts "class method #{self}"
end
end
C.classmethod # class method C
c = C.new
def c.singletonmethod
puts "instance method #{self}"
end
c.singletonmethod # instance method #<C:0x0000000118ed08>
答案 0 :(得分:17)
Ruby中发生的大多数事情涉及包含的类和模块 实例方法的定义
class C
def talk
puts "Hi!"
end
end
c = C.new
c.talk
Output: Hi!
但正如您之前看到的(甚至比您在类中看到实例方法更早),您还可以直接在单个对象上定义单例方法:
obj = Object.new
def obj.talk
puts "Hi!"
end
obj.talk
#377
#Output: Hi!
在给定对象上定义单例方法时,只有该对象可以调用该方法。正如您所见,最常见的单例方法类型是类方法 - 一种基于个体添加到Class对象的方法:
class Car
def self.makes
%w{ Honda Ford Toyota Chevrolet Volvo }
end
end
但是任何对象都可以添加单例方法。基于每个对象定义方法驱动行为的能力是Ruby设计的标志之一。
Singleton类是匿名的:虽然它们是类对象(类Class的实例),但它们会自动弹出而不会给出名称。尽管如此,您可以打开单例类的类定义主体,并向其添加实例方法,类方法和常量,就像使用常规类一样。
注意:强>
<强> Every object has two classes:
强>
■它是一个实例的类
■其单身类
1:The Ruby Object Model and Metaprogramming有关 singleton method vs. class method ruby
2:MetaProgramming - Extending Ruby for Fun and Profit - Dave Thomas
希望这能帮到你!!!
答案 1 :(得分:16)
没有区别。 Ruby中没有类方法。如果对象恰好是mutateAndGetPayload: ({clientMutationId, ...args}) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Resolved")
}, 500)
})
}, ...
类的实例,“类方法”只是我们人类调用单例方法的名称。
答案 2 :(得分:6)
在ruby类中也是一个对象。因此,在您的示例中,classmethod
是对象C
的单例方法,而singletonmethod
是对象c
的单例方法。
我强烈推荐Paolo Perrotta的书“Metaprogramming Ruby”。
答案 3 :(得分:3)
由于所有方法都是由类定义实现和存储的,因此对象不可能定义自己的方法。但是,Ruby提供了一种方法 - 您可以定义仅适用于特定对象的方法。这种方法称为Singleton方法。
class Instance
def instance_method
puts "instance method called"
end
end
in_obj = Instance.new
上面的语句你是Instance类的引用对象,你可能得到一个不同的id。
#<Instance:0x00000000e9ee68>
让我们用对象调用实例方法,我们将得到输出。
in_obj.instance_method
instance method called
现在,创建单例方法。
sin_obj = Instance.new
#<Instance:0x00000000e98d60>
def sin_obj.singleton_method
puts "singleton method called"
end
调用单例方法
sin_obj.sigleton_method
singleton method called
这里,对象sin_obj具有单例方法singleton_method。这是一个 单例方法因为它只属于一个类的一个实例 并且不会与他人分享。
但是,单例方法与实例对象不相矛盾 hold方法,只有类定义(Class类的对象)才可以。它 碰巧说实话介于两者之间。 当您在对象上声明单例方法时,Ruby会自动创建一个类来保存该方法。该类称为对象的“元类”。此对象的所有后续单例方法都转到其元类。每当您向对象发送消息时,它首先会查看该方法是否存在于其元类中。如果它不存在,它将传播到对象的实际类,如果在那里找不到,则消息遍历继承层次结构。 我们在同一个Instance类中定义类方法。 现在,让我们通过一个例子检查上面我的统计数据。
foo = "Hey I am a string"
def foo.foo_instance_method
p self.upcase
end
验证signleton方法定义转到元类的事实。
p foo.class.instance_methods.include?:foo_instance_method
false
p foo.metaclass.instance_methods.include?:foo_instance_method
true
p foo.metaclass.class
Class
p foo.metaclass
#<Class:#<String:0x00000000e8f0f8>>
让我们看看如何实现元类。
class Instance
def metaclass
class << self
self
end
end
end
班级&lt;&lt; self语法将当前self更改为指向当前对象的元类。由于我们已经在实例方法中,因此这将是实例的元类。该方法只返回self,此时是实例的元类。
元类在很多方面几乎都是一个类。但它不可能 实例化。要查看此内容,请参阅下面的示例。
a = Instance.new
a.metaclass.new
You will get is error when try to intantiate the meta class.
*TypeError: can't create instance of singleton class*
在Ruby中,'metaclass'和'singleton class'都意味着相同。你会 发现它们在Ruby文献中可以互换使用。
class Instance
def self.class_method #instead one can use def Instance.class_method
puts "class method called"
end
end
class Instance
class << self
def show
puts "Class method show invoked"
end
end
end
调用class_method
Instance.class_method
class method called
Instance.show
Class method show invoked
它包括仅为当前对象(self)构建一个新的匿名类。要创建匿名类,我们使用&lt;&lt;符号。仔细查看如何定义类方法和单例方法,找到差异。 考虑这个例子。
class Instance
puts self
def meth
p self
end
end
这里,在方法之外,self只是类,在instance_method中指向当前实例或对象的self。
此外,您还可以检查方法是否响应特定对象。
p Instance.new.respond_to?(:singleton_method)
p Instance.new.respond_to?(:class_method)
答案 4 :(得分:0)
他们是相对的观念;透视问题。从A类的单例类的角度来看,它的实例方法是从A(A实例)的角度来看的类方法。