Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby隐藏与重写_Ruby_Overriding_Method Hiding - Fatal编程技术网

Ruby隐藏与重写

Ruby隐藏与重写,ruby,overriding,method-hiding,Ruby,Overriding,Method Hiding,我刚刚了解到,在Java中,重写和隐藏(静态方法是隐藏的,而不是重写的)是有区别的,这意味着Java同时使用早期绑定和晚期绑定 是否有类似于方法隐藏的东西,或者它只是有方法覆盖?Java有三种不同的“方法”:实例方法、静态方法和构造函数。Ruby只有一个:实例方法 在Java中,静态方法的行为必须不同于实例方法,因为类不是对象。它们没有类,因此没有超类,因此没有可重写的内容。在Ruby中,类和其他对象一样都是对象,它们有一个类,可以有一个超类,因此子类可以覆盖超类方法 注意:您可能听说过Ruby

我刚刚了解到,在Java中,重写和隐藏(静态方法是隐藏的,而不是重写的)是有区别的,这意味着Java同时使用早期绑定和晚期绑定


是否有类似于方法隐藏的东西,或者它只是有方法覆盖?

Java有三种不同的“方法”:实例方法、静态方法和构造函数。Ruby只有一个:实例方法

在Java中,静态方法的行为必须不同于实例方法,因为类不是对象。它们没有类,因此没有超类,因此没有可重写的内容。在Ruby中,类和其他对象一样都是对象,它们有一个类,可以有一个超类,因此子类可以覆盖超类方法

注意:您可能听说过Ruby中的类方法或单例方法。那是谎言。好吧,这不是谎言。这是我们使用的一个方便的速记,因为“类方法”比“类对象的单例类的常规实例方法”更容易发音……但事实正是如此。没有类方法

在Ruby中,每个对象都可以有自己的方法。这些被称为“单例方法”。类是与任何其他对象一样的对象,因此它们也可以有单例方法。当单例方法所属的对象是类时,我们称该方法为类方法。但这正是我们所说的,类方法和单例方法之间没有区别

实际上,在Ruby中,每个对象都有一个单例类。singleton类与对象的关系为1:1:对象只有一个singleton类,每个singleton类只有一个实例,即它的对象。那么,当我在上面提到对象可以有方法时,这些方法称为单例方法?那也是个谎言。单例方法实际上只是标准实例方法,它恰好是在对象的单例类中定义的,因此只能在该对象上调用(因为该对象是其单例类的唯一实例)

因此,当一个方法在一个单例类中定义时,我们称之为单例方法,当单例类属于一个类时,我们称之为类方法,但都只是实例方法。(顺便说一句:模块的工作方式是相同的。在这种情况下,它们被称为模块方法或有时称为“模块函数”。)

对象的
class
指针始终指向其单例类。然后,对象的实际类是单例类的
超类
,即单例类的
超类
指针指向对象的实际类。(除非存在mixin,mixin将成为它们所混合到的类的超类,因此如果将模块混合到单例类中,则模块将成为单例类的超类,而旧的超类将成为模块的超类,或者更确切地说是其包含代理类。)

这意味着方法查找,这是OO语言中最常执行的操作,变得非常简单和快速:抓取对象,抓取其
指针,查看方法是否存在,抓取超类指针,查看方法是否存在,抓取超类指针……直到找到方法

这确实意味着反射变得更加复杂,但反射并不是一个性能关键的操作。例如,如果您向一个对象请求它的类,您不能简单地返回
指针,因为它始终是它的单例类,因此信息量不大。你必须得到超类,以及超类的超类等等,直到你最终得到一个不是单例类或include代理类的类

但是方法查找本身非常简单,
super
总是按照您的期望执行

特别是,当您创建一个新类时,超类的singleton类将成为子类的singleton类的超类,因此“类方法”就像您所期望的那样被继承

因此,概括一下:虽然Java有三种不同类型的“方法”,它们具有不同的继承行为(实例方法被继承,静态方法不被继承,构造函数被继承,但有这个
super
调用限制),但Ruby只有一种。但是,它有三种不同类型的类:常规类、单例类和包含代理类(在将模块混合到类中时创建为mixin的代理)。后两个在YARV内部也称为“虚拟类”,YARV是使用最广泛的Ruby实现

最后一件事:还有所谓的“全局方法”,有时称为“全局过程”或“全局函数”。同样,正如你可能已经猜到的,这些是不存在的。当您在任何类之外定义方法时,它隐式地成为
Object
的私有实例方法,因此可用于每个对象

[我在这里忽略了两件事:
BasicObject
prepend
。这些事情有点复杂,尤其是后者。但主要的心理模型仍然存在。]