当前位置 : 主页 > 编程语言 > ruby >

setter方法和虚方法(在Ruby中)之间有什么区别?

来源:互联网 收集:自由互联 发布时间:2021-06-23
我正在研究 Ruby并试图绕过一些词汇.在某个地方,我提到了一个概念,即setter概念也是一种虚方法,即它们是同义词.但现在我觉得我错了.我想知道这些与工厂方法有什么关系.救命? 维基百
我正在研究 Ruby并试图绕过一些词汇.在某个地方,我提到了一个概念,即setter概念也是一种虚方法,即它们是同义词.但现在我觉得我错了.我想知道这些与工厂方法有什么关系.救命?

维基百科说这关于虚拟方法:

In object-oriented programming, in languages such as C++, a virtual
function or virtual method is an inheritable and overridable function
or method for which dynamic dispatch is facilitated.

自去年六月以来,我一直在努力学习Ruby,我不知道这意味着什么.

我对setter方法有一个更好的概念.我一直在想它只是设置实例变量值的任何方法.所以attr_writer:foo是一个setter方法,也许一个改变foo值的类外部的方法也可以是一个setter方法.是对的吗?

但这不是“虚拟方法”的意思,是吗?所以基本上,我正在寻找差异的解释,我找不到任何(或者,我不能理解).

所谓的“工厂方法”也可以被描述为从类外部创建特定类型的对象(由setter方法集合指定)的方法(即,定义类的代码)?

Somewhere I picked up the notion that a setter notion is also a virtual method, i.e., they’re synonyms.

这是一个逻辑错误:狗也是一个哺乳动物,但这并不意味着它们是同义词.

同样,在Ruby中,setter方法也是虚方法(因为在Ruby中所有方法都是虚方法),但它们不是同义词.由于Ruby中只有虚拟方法,你也可以说:setter方法也是方法.现在,显而易见的是,这并不一定意味着方法也是setter方法,对吗?

Wikipedia says this about virtual methods:

In object-oriented programming, in languages such as C++, a virtual
function or virtual method is an inheritable and overridable function
or method for which dynamic dispatch is facilitated.

这个术语在Ruby中没有意义,因为在Ruby中,所有方法都是虚拟的,因此不需要区分虚拟方法和非虚方法.

在OOP中,术语“虚拟”适用于语言 – 动态分配的“事物”(即在运行时)并且可以被覆盖.

class Foo
  def to_s
    foo
  end

  def foo
    'Foo'
  end
end

class Bar < Foo
  def foo
    'Bar'
  end
end

Bar.new.to_s
#=> 'Bar'

如您所见,Bar.new.to_s返回字符串’Bar’,即使to_s在Foo中定义并且只是调用foo.然而,即使to_s在Foo中定义,它也不会调用Foo的foo,它会调用Bar的foo,因为有问题的对象有类Bar. Bar已经用自己的方法覆盖了foo的定义,并且调用被动态地调度到当前对象具有的任何类.

创造了“面向对象”一词的Alan Kay使用了一个消息传递隐喻,即恕我直言使这样的事情更容易理解:对象通过发送消息相互通信.它就像你在现实世界中向某人发送消息一样:你无法知道接收者对消息做了什么,你所能观察到的就是你得到的回应.当您向某人发送消息时,他们将根据自己的知识解释消息中的请求.

所以,如果你想象你和你朋友之间的这种交流:

>您将消息“将自己转换为字符串”发送给朋友.
>你的朋友不知道这意味着什么,所以他问他的上级,他告诉他,这意味着“给自己发信息’foo’”.
>你的朋友给自己发了一条消息“foo”.
>你的朋友对“foo”的含义有他自己的想法,所以他不需要查阅它.

其他语言具有其他虚拟“事物”,例如Newspeak有虚拟超类.

所以,如果我有这个:

class Foo < Array
  # … stuff
end

class Bar
  def Array
    return SomeClassLikeArray
  end

  def bar
    Foo.new
  end
end

Bar.new.bar
# this will be a `Foo` which has `SomeClassLikeArray` as its superclass

I do have a little better notion of what setter methods are. I’ve been thinking that it is just any method that sets the value of an instance variable.

是的,不是.

这是一种似乎设置实例变量的方法.您实际上并不知道该方法的作用. (记住消息传递比喻:你只能观察你朋友的回答,你不知道你的朋友对这个消息做了什么!)

例如,在Web框架中,setter方法实际上可以写入数据库而不是设置实例变量.

一般来说,在Ruby中,setter方法是一个名称以=结尾的方法.

So attr_writer :foo is a setter method,

不,那不是一个setter方法. It creates a setter method named foo=.

and maybe a method external to a class that changes the value of foo would also be a setter method. Is that right?

这不是我们通常所说的setter方法.它在Ruby中也是不可能的,因为只有对象本身才能访问其实例变量.

即使在允许它的语言中,也是糟糕的设计:对象应该做东西,而不是存储东西.这是关于行为.您应该告诉对象执行操作.

But that’s not what “virtual method” means, is it? So basically, I’m looking for an explanation of the differences and I can’t find any (or, not that I can understand).

由于这两个概念是完全正交的,所以谈论它们的差异并没有多大意义;他们没有任何关系.

虚方法是一种可以被覆盖的方法. setter方法是一种设置东西的方法.您可以使用可以覆盖的setter方法,无法覆盖的setter方法,可以覆盖的非setter方法以及无法覆盖的非setter方法.

特别是在Ruby中,所有方法都是虚拟的,因此所有setter方法都是虚拟的(因为所有setter方法都是方法),但就是这样.

It’s also the case, isn’t it, that a so-called “factory method” could be described as method to create an object of a particular type, as specified by a collection of setter methods, from outside of the class (i.e., the code defining the class)?

所以,有一个Design Pattern called Factory Method,但你在谈论创建对象的方法的更一般的概念.

是的,创建对象的方法是sometimes called “Factory Method”.在Ruby中,最广泛使用的工厂方法是新的,which looks something like this:

class Class
  def new(*args, &block)
    obj = allocate
    obj.initialize(*args, &block)
    return obj
  end
end

实际上,initialize是一个私有方法,因此我们需要使用反射来规避访问保护,但这并不会改变方法的要点:

class Class
  def new(*args, &block)
    obj = allocate
    obj.__send__(:initialize, *args, &block)
    return obj
  end
end
网友评论