有人能简单解释OOP环境中的方法与函数吗?


当前回答

它们通常是可互换的,但方法通常指类内的子例程,函数通常指类外的子例程。例如,在Ruby中:

# function
def putSqr(a)
   puts a ** 2
end


class Math2
   # method
   def putSqr(a)
      puts a ** 2
   end
end

在Java中,所有内容(包和导入语句除外)都必须在类中,人们几乎总是将它们称为“方法”。

其他回答

在Object Pascal或C++等OO语言中,“方法”是与对象关联的函数。因此,例如,“狗”对象可能具有“吠叫”功能,这将被视为“方法”。相反,“StrLen”函数是独立的(它提供作为参数提供的字符串的长度)。因此,它只是一个“函数”。Javascript在技术上也是面向对象的,但与C++、C#或Pascal这样的成熟语言相比,它面临许多限制。尽管如此,这种区别仍然存在。

另外还有几个事实:C#是完全面向对象的,因此您无法创建独立的“函数”。在C#中,每个函数都绑定到一个对象,因此从技术上讲,都是一个“方法”。关键是,在C#中很少有人将它们称为“方法”-他们只是使用“函数”一词,因为没有任何真正的区别。

最后,为了让任何Pascal专家都不要跳到我这里,Pascal还区分了“函数”(返回值)和“过程”(不返回值)。C#并没有明确区分这一点,当然,您可以选择是否返回值。

方法与功能的区别

在Microsoft上阅读此文档

包含可执行代码的成员统称为类的函数成员。上一节描述了方法,它们是函数成员的主要类型。本节介绍C#支持的其他类型的函数成员:构造函数、财产、索引器、事件、运算符和终结器。

所以方法是函数的子集。每个方法都是一个函数,但不是每个函数都是一种方法,例如,构造函数不能被称为方法,但它是一种函数。

函数是一个数学概念。例如:

f(x,y) = sin(x) + cos(y)

表示函数f()将返回第一个参数的sin加上第二个参数的余弦。这只是数学。碰巧sin()和cos()也是函数。函数有另一个属性:对具有相同参数的函数的所有调用都应返回相同的结果。

另一方面,方法是与面向对象语言中的对象相关的函数。它有一个隐式参数:被作用的对象(及其状态)。

因此,如果对象Z具有方法g(x),则可能会看到以下内容:

Z.g(x) = sin(x) + cos(Z.y)

在这种情况下,传入参数x,与前面的函数示例相同。然而,cos()的参数是位于对象Z内部的值。Z和位于对象Z内的数据(Z.y)是Z的g()方法的隐式参数。

TL;博士

函数是一段要运行的代码。方法是对象内的函数。

函数示例:


function sum(){
  console.log("sum")l
}

方法示例:

const obj = {
a:1,
b:2,
sum(){
  }
}

所以这就是为什么我们说函数中的“this”关键字不是很有用,除非我们将其与call、apply或bind一起使用。。因为call、apply、bind将作为对象内部的方法调用该函数==>基本上它将函数转换为方法

只需两个字:非静态(“instance”)方法将一个隐藏指针指向“this”(作为其第一个参数),该对象就是您调用该方法的对象。

这是与常规独立函数的唯一区别,尽管是动态调度。

如果您感兴趣,请阅读以下详细信息。

我将尽量简短,并将使用C++作为示例,尽管我所说的几乎可以应用于每种语言。

对于您的CPU来说,函数和方法都只是一段代码。时期因此,当调用函数/方法时参数

好吧,我说过没有实际的区别。让我们再深入一点:

有两种类型的方法:静态和非静态静态方法类似于常规函数,但在类内部声明,该类的作用仅类似于命名空间非静态(“instance”)方法采用指向“this”的隐藏指针。这是与常规独立函数的唯一区别。

撇开动态调度不谈,这意味着它非常简单:

class User {
    public string name; // I made it public intentionally

    // Each instance method takes a hidden reference to "this"
    public void printName(/*User & this*/) {
        cout << this.name << endl;
    }
};

相当于

public getName(User & user) {
    // No syntactic sugar, passing a reference explicitly
    cout << user.name << endl;
}

因此,本质上,user->printName()只是getName(user)的语法糖。

如果不使用动态调度,仅此而已。如果使用了它,那么它就有点复杂了,但是编译器仍然会发出一个看起来像函数的东西,将其作为第一个参数。