单身方法与类方法
类方法和单例方法是相同还是不同? 这是一个例子。
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 #
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设计的标志之一。
单身人士课程
单例类是匿名的:尽管它们是类对象(类Class的实例),但它们会自动弹出而不会给出名称。 尽管如此,您可以打开单例类的类定义主体,并向其添加实例方法,类方法和常量,就像使用常规类一样。
注意:
Every object has two classes:
■它是一个实例的类
■它的单身人士课程
————————————————– ————–
在最后,我强烈建议你观看。
1: Ruby对象模型和元编程有关singleton method vs. class method ruby
详细信息
2: MetaProgramming – 为了娱乐和利润而扩展Ruby – 由Dave Thomas
撰写
希望这能帮到你!!!
没有区别。 Ruby中没有类方法。 如果对象碰巧是Class
类的一个实例,那么“类方法”只是我们人类称之为单例方法的名称。
在ruby类中也是一个对象。 因此,在您的示例中, classmethod
是对象C
singletonmethod
例方法,而singleton方法是对象c
单例方法。
我强烈推荐Paolo Perrotta的书“Metaprogramming Ruby”。
由于所有方法都是由类定义实现和存储的,因此对象不可能定义自己的方法。 但是,Ruby提供了一种方法 – 您可以定义仅适用于特定对象的方法。 这种方法称为Singleton方法。
class Instance def instance_method puts "instance method called" end end in_obj = Instance.new
上面的语句你是Instance类的引用对象,你可能得到一个不同的id。
#
让我们用对象调用实例方法,我们将得到输出。
in_obj.instance_method instance method called
现在,创建单例方法。
sin_obj = Instance.new # def sin_obj.singleton_method puts "singleton method called" end
调用单例方法
sin_obj.sigleton_method singleton method called
这里,对象sin_obj具有单例方法singleton_method。 这是一个单例方法,因为它只属于一个类的一个实例,不会与其他实例共享。
但是,单例方法与实例对象不能保存方法相矛盾,只有类定义(类Class的对象)才能。 碰巧真相介于两者之间。 当您在对象上声明单例方法时,Ruby会自动创建一个类来保存该方法。 该类称为对象的“元类”。 此对象的所有后续单例方法都转到其元类。 每当您向对象发送消息时,它首先会查看该方法是否存在于其元类中。 如果它不存在,它将传播到对象的实际类,如果在那里找不到,则消息遍历inheritance层次结构。 让我们在同一个Instance类中定义类方法。 现在,让我们通过一个例子检查上面我的统计数据。
foo = "Hey I am a string" def foo.foo_instance_method p self.upcase end
validationsignleton方法定义转到元类的事实。
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 Instance def metaclass class << self self end end end
类<< 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)构建一个新的匿名类。 要创建匿名类,我们使用<<表示法。 仔细查看如何定义类方法和单例方法,您会发现差异。 考虑这个例子。
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)
他们是相对的观念; 透视问题。 从A类单例类的角度来看,它的实例方法是一个从A(实例)的角度来看的类方法。