方法和函数有什么区别?

2149

能否简单解释一下在面向对象编程中方法函数的区别?


看到另一种解释来阐述 [tag:r] 中方法和函数的区别会很有趣。这很有趣,因为方法通常会包含一个函数。如果方法是一个依赖于对象的函数,那么检查对象类别的函数 if(class(object)) { ... } else {stop()} 在概念上等同于方法吗? - Konrad
1
适当的术语可能因语言而异,在不同的上下文中可能略有不同的含义。即便如此,由于程序员在使用一种语言时更习惯于某些术语,因此他们会受到同事使用术语的影响(无论其是否正确)。这些术语通常可以互换使用。例如,请参见以下一些评论。 - jvriesem
关于概念混淆的问题提得非常好。我喜欢程序员们的哲学意识。谢谢大家。 - Berkay
42个回答

16

历史上,“方法”和“函数”的微小区别在于,“方法”不返回任何值,而“函数”则会返回值。每种语言都有自己的专业术语表。

在“C”中,“function”指代程序的例程。

而在Java中,“function”一词没有任何特殊含义。而“method”则是类的实现之一。

在C#中,这可以翻译为:

public void DoSomething() {} // method
public int DoSomethingAndReturnMeANumber(){} // function

但实际上,我再次强调这两个概念没有任何区别。 如果您在讨论Java的非正式讨论中使用术语“function”,人们会认为您是指“method”,并继续讨论。不要在关于Java的正式文档或演示中使用它,否则您看起来会很傻。


实际上,在您的示例中,两者都是“方法”... 或者我会称之为“过程”和“函数”。 - Yousha Aleayoub

16

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

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

它说明函数f()将返回第一个参数的正弦加上第二个参数的余弦。这只是数学。恰好sin()和cos()也是函数。函数有另一个属性:对于所有传入相同参数的函数调用,应该返回相同的结果。

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

因此,如果您有一个名为Z的对象,其中包含一个名为g(x)的方法,则可能会看到以下内容:

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

在这种情况下,参数x被传递进来,与之前的函数示例中一样。然而,cos()函数的参数是存在于对象Z中的值。Z以及其内部存在的数据(Z.y)是Z的g()方法的隐式参数。


14

函数或方法是一段带有名称的可调用代码,执行某些操作并可选择返回值。

C语言中使用术语函数。 JavaC#中人们会称其为方法(在这种情况下,函数是在类/对象内定义的)。

C++程序员可能称其为函数,有时也称其为方法(这取决于他们是否编写过程式C++代码还是采用面向对象的方式编写C++。而只熟悉C/C++的程序员可能会称之为函数,因为“方法”一词在C/C++文献中使用不太频繁)。

通过调用函数名来使用函数,如:

result = mySum(num1, num2);
您需要通过引用其对象来调用方法,例如,
result = MyCalc.mySum(num1,num2);

13

函数是一组用于操作数据的逻辑。

而方法是用于操作其所属对象的数据的函数。 因此,从技术上讲,如果您有一个不完全与类相关但在类中声明的函数,则它不是方法;这被称为糟糕的设计。


非常好而且简洁的描述。 - Mohy Eldeen

11
在面向对象的编程语言(如Object Pascal或C++)中,“方法”是与一个对象相关联的函数。例如,一个“Dog”对象可能有一个“bark”函数,这被认为是一个“方法”。相比之下,“StrLen”函数是独立存在的(它提供了作为参数提供的字符串的长度)。因此,它只是一个“函数”。虽然JavaScript也技术上是面向对象的,但与像C++、C#或Pascal这样的完整语言相比,它面临许多限制。尽管如此,这种区别仍然应该适用。
另外需要指出的是:C#是完全面向对象的,因此您不能创建独立的“函数”。在C#中,每个函数都绑定到一个对象,并因此技术上是一个“方法”。关键在于,在C#中很少有人将它们称为“方法”,他们只使用术语“函数”,因为没有任何真正的区别需要进行区分。
最后 - 只要Pascal专家不在这里找我茬 - Pascal还区分“函数”(返回值)和“过程”(不返回值)。尽管您当然可以选择返回值或不返回值,但C#没有明确做出这种区别。

10

类中的方法作用于类的实例,也称为对象。

class Example
{
   public int data = 0; // Each instance of Example holds its internal data. This is a "field", or "member variable".

   public void UpdateData() // .. and manipulates it (This is a method by the way)
   {
      data = data + 1;
   }

   public void PrintData() // This is also a method
   {
      Console.WriteLine(data);
   }
}

class Program
{
   public static void Main()
   {
       Example exampleObject1 = new Example();
       Example exampleObject2 = new Example();

       exampleObject1.UpdateData();
       exampleObject1.UpdateData();

       exampleObject2.UpdateData();

       exampleObject1.PrintData(); // Prints "2"
       exampleObject2.PrintData(); // Prints "1"
   }
}

10

由于您提到了Python,以下内容可能是大多数现代面向对象语言中方法和对象之间关系的有用说明。简而言之,所谓的“方法”就是只是一个被传递了额外参数的函数(正如其他答案已经指出的那样), 但Python比大多数其他语言更明确地表达了这一点。

# perfectly normal function
def hello(greetee):
  print "Hello", greetee

# generalise a bit (still a function though)
def greet(greeting, greetee):
  print greeting, greetee

# hide the greeting behind a layer of abstraction (still a function!)
def greet_with_greeter(greeter, greetee):
  print greeter.greeting, greetee

# very simple class we can pass to greet_with_greeter
class Greeter(object):
  def __init__(self, greeting):
    self.greeting = greeting

  # while we're at it, here's a method that uses self.greeting...
  def greet(self, greetee):
    print self.greeting, greetee

# save an object of class Greeter for later
hello_greeter = Greeter("Hello")

# now all of the following print the same message
hello("World")
greet("Hello", "World")
greet_with_greeter(hello_greeter, "World")
hello_greeter.greet("World")
现在比较函数greet_with_greeter和方法greet:唯一的区别是第一个参数的名称(在函数中我将其称为“greeter”,在方法中我将其称为“self”)。因此,我可以像使用greet_with_greeter函数一样使用greet方法(使用“点”语法获取它,因为我在类内定义了它):
Greeter.greet(hello_greeter, "World")

所以我已经成功地将一个方法变成了函数。那么,我能将一个函数变成方法吗?嗯,因为Python允许你在定义后修改类,那我们试一下:

Greeter.greet2 = greet_with_greeter
hello_greeter.greet2("World")

是的,函数greet_with_greeter现在也被称为方法greet2。这展示了方法和函数之间唯一的真正区别:当你通过调用object.method(args)来调用一个对象上的方法时,语言会自动将其转换为method(object, args)

(面向对象的纯粹主义者可能会认为方法与函数有所不同,如果你深入学习Python、Ruby或Smalltalk等高级编程语言,你会开始理解他们的观点。此外,某些编程语言赋予方法对对象的某些位的特殊访问权限。但最主要的概念性区别仍然是隐藏的额外参数。)


9
对我来说: 如果我同意以下内容,则方法和函数的功能是相同的:
  • 函数可以返回一个值
  • 可能期望参数
就像任何一段代码一样,您可能有要放入的对象,并且可能会得到一个结果对象。在执行此操作时,它们可能会更改对象的状态,但这不会改变它们的基本功能。
调用对象或其他代码的函数可能存在定义差异。但这难道不是口头区别的事情吗?这就是人们交换它们的原因吗?提到计算的示例,我会小心处理,因为我雇用员工来做我的计算。
new Employer().calculateSum( 8, 8 );

通过这种方式,我可以依赖雇主负责计算。如果他想要更多的钱,我会释放他并让垃圾收集器函数处置未使用的员工并招聘新员工。
即使争论一个方法是对象函数,而函数是不相关的计算,也无法帮助我。函数描述符本身以及理想情况下函数的文档将告诉我它需要什么和可能返回什么。其余的,如操作某个对象的状态对我来说并不是真正透明的。我期望函数和方法都能够交付和操作它们所声称的内容,而不需要详细了解它们如何实现。即使是纯计算函数也可能改变控制台的状态或附加到日志文件中。

7

让我们不要把本该非常简单的问题复杂化。方法和函数是相同的东西。当函数在类外部时,你称之为函数;而当它写在类内部时,你称之为方法。


6

个人认为,人们只是想发明一个新词,使程序员更容易地进行交流,当他们想要引用对象内部的函数时。

如果您说方法(methods),则指类中的函数。如果您说函数(functions),则只是指类外的函数。

事实上,这两个词都用于描述函数。即使您使用错误也没有关系,这两个词都可以很好地描述您在代码中要实现的内容。

函数是一段有特定作用(a function)的代码。方法是解决问题的a method

它们做同样的事情。它们是相同的东西。如果您想非常精确并遵循约定,可以将方法称为对象内的函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接