ChatGPT解决这个技术问题 Extra ChatGPT

方法和函数有什么区别?

有人可以在 OOP 上下文中提供方法与函数的简单解释吗?

r 中看到另一种概述方法和函数之间差异的解释会很有趣。这很有趣,因为方法通常会contain a function。如果方法是一个依赖于对象的函数,那么对象类 if(class(object)) { ... } else {stop()} 的函数检查在概念上就等同于方法?
正确的术语实际上可能取决于语言,因此在不同的上下文中它可能意味着略有不同的东西。即便如此,因为使用一种语言而不是另一种语言的程序员更习惯于某些术语。程序员也会受到同事对术语的使用(无论正确与否)的影响。这些术语经常互换使用。例如,请参阅下面的一些评论。

N
Nhan

函数是一段按名称调用的代码。它可以传递数据进行操作(即参数),也可以选择返回数据(返回值)。传递给函数的所有数据都是显式传递的。

方法是一段由与对象关联的名称调用的代码。在大多数方面,它与函数相同,除了两个关键区别:

方法被隐式传递给调用它的对象。方法能够对包含在类中的数据进行操作(请记住,对象是类的实例——类是定义,对象是该数据的实例)。

(这是一个简化的解释,忽略 scope 等问题)


对于 1),您还应该添加 C++ 中的方法称为成员函数。因此,在这种情况下,函数和方法之间的区别类似于 C++ 中函数和成员函数之间的区别。此外,像 Java 这样的语言只有方法。在这种情况下,函数类似于静态方法,并且方法具有相同的含义。对于 2),您应该添加一个方法能够对声明为类的一部分的私有实例(成员)数据进行操作。任何代码都可以访问公共实例数据。
函数是一种数学结构。我会说所有方法都是函数,但并非所有函数都是方法
来自函数式编程背景,我觉得函数和方法之间有着深刻的区别。主要是方法有副作用,函数应该是纯的,因此提供了相当好的引用透明性
@TylerGillies 和HHC,我同意如果“功能”和“方法”的意思是您想要的那样可能会很好,但是您的定义并未反映这些术语的一些非常常见的用法。
根据这个定义,静态方法实际上不会被视为方法,因为它与特定实例没有任何关系?
T
Top-Master

方法在对象上或在类中是静态的。函数独立于任何对象(并且在任何类之外)。

对于 Java 和 C#,只有方法。对于 C,只有函数。

对于 C++ 和 Python,这取决于你是否在课堂上。但在基础英语中:

功能:独立的特性或功能。

方法:做某事的一种方式,它具有不同的方法或方法,但与同一方面(又名类)相关。


类中的静态方法怎么样?这些将独立于一个对象(在java中)。那不就是一个函数吗?
在 Scala 中:函数 可以使用参数列表调用函数以产生结果。函数具有参数列表、主体和结果类型。作为类、特征或单例对象成员的函数称为方法。在其他函数中定义的函数称为局部函数。结果类型为 Unit 的函数称为过程。源代码中的匿名函数称为函数字面量。在运行时,函数字面量被实例化为称为函数值的对象。 Scala 第二版编程。 Martin Odersky - Lex Spoon - Bill Venners
@Squeazer 最近有一个问题stackoverflow.com/questions/30402169/…Java 语言规范只是将它们区分为“类方法”(静态)和“实例方法”。所以它们仍然是所有方法。
Java 有 lambda 表达式,它们是不是方法的函数
Python中有方法和函数。
C
Community

“方法”是“功能”的面向对象的词。这几乎就是它的全部内容(即,没有真正的区别)。

不幸的是,我认为这里的很多答案都在延续或推进存在一些复杂、有意义的差异的想法。

真的 - 没有那么多,只是对同一件事有不同的说法。

[后期补充]

事实上,正如 Brian Neal 在对 this question 的评论中指出的那样,C++ 标准在提及成员函数时从不使用术语“方法”。有些人可能会认为这表明 C++ 并不是真正的面向对象语言。但是,我更愿意将其视为一个非常聪明的群体认为没有特别充分的理由使用不同术语的迹象。


方法是一种特殊类型的函数,它传递了一个隐式参数(定义该方法的类的实例)。这很重要,因为严格来说,函数不应使用或修改不在其参数列表中的任何内容。
@ty1824 方法并不总是传递隐式参数。在 Python 中,self 参数是显式的。而且许多语言都有静态方法,它们不传递实例。
@mheiber 这些是一些有效的观点。关于自我,您是正确的,它是明确定义的。关键是调用是隐式的,基于原始对象引用。有些语言支持覆盖 thisself,但这些结构通常称为函数,而不是方法。
@mheiber就静态方法而言-java将它们作为一种解决方法实现,因此可以在不需要上下文的情况下实现功能。我什至会提出“静态方法”是一个误导性术语,应该被替换......在理想的理论世界中:)
@ty1824 C++、Scala、Python、Ruby、JavaScript 和 Scala 都有静态方法,所以我不认为它只是 Java 的东西。我也不喜欢它们:它们相当于使用对象(状态包),就好像它们是命名空间一样。
E
Edric

一般来说:方法是属于一个类的函数,函数可以在代码的任何其他范围内,因此您可以声明所有方法都是函数,但并非所有函数都是方法:

以以下 python 示例为例:

class Door:
  def open(self):
    print 'hello stranger'

def knock_door:
  a_door = Door()
  Door.open(a_door)

knock_door()

给出的示例向您展示了一个名为“Door”的类,它有一个名为“open”的方法或动作,它被称为方法,因为它是在一个类中声明的。代码的另一部分“def”就在下面,它定义了一个函数,它是一个函数,因为它没有在类中声明,这个函数调用我们在类中定义的方法,如你所见,最后这个函数被自己调用。

如您所见,您可以在任何地方调用函数,但是如果要调用方法,则必须传递与声明该方法的类相同类型的新对象(Class.method(object)),或者必须调用对象内部的方法(object.Method()),至少在python中。

将方法视为只有一个实体可以做的事情,所以如果你有一个 Dog 类,那么只在该类内部有一个 bark 函数是有意义的,这将是一个方法,如果你还有一个 Person 类,它可能是有意义的为它写一个不属于任何类的函数“feed”,因为人类和狗都可以被喂食,你可以称它为一个函数,因为它不属于任何特定的类。


这个答案——主要是它的第一句话——是迄今为止对该问题最简洁和整体的最佳答案。
D
Duc Filan

简单的记忆方法:

函数→自由(自由意味着它可以在任何地方,不需要在对象或类中)

方法→成员(对象或类的成员)


既然通常可以互换,为什么需要助记符?
@Sapphire_Brick 我假设它们不可互换的情况。
A
Andrew Tobilko

函数和方法之间主要区别的一个非常笼统的定义:

函数是在类之外定义的,而方法是在类内部和类的一部分中定义的。


5
5 revs, 2 users 99%

面向对象范式背后的想法是“对待”软件由......以及“对象”组成。现实世界中的对象具有属性,例如,如果您有一个员工,该员工有一个姓名、一个员工 ID、一个职位、他属于一个部门等等。

对象也知道如何处理它的属性并对它们执行一些操作。假设我们想知道员工现在在做什么,我们会问他。

employe whatAreYouDoing.

“whatAreYouDoing”是发送给对象的“消息”。对象知道如何回答这些问题,据说它有解决问题的“方法”。

因此,对象必须公开其行为的方式称为方法。因此,方法是工件对象必须“做”某事。

其他可能的方法是

employee whatIsYourName
employee whatIsYourDepartmentsName

等等

另一方面,函数是编程语言必须计算某些数据的方式,例如,您可能拥有返回 16 的函数 addValues( 8 , 8 )

// pseudo-code
function addValues( int x, int y )  return x + y 
// call it 
result = addValues( 8,8 )
print result // output is 16...

由于第一个流行的编程语言(例如 fortran、c、pascal)没有涵盖 OO 范式,它们只调用这些工件“函数”。

例如,C 中的前一个函数是:

int addValues( int x, int y ) 
{
   return x + y;
}

说一个对象有一个“函数”来执行某些操作是不“自然的”,因为函数与数学的东西更相关,而 Employee 几乎没有数学,但你可以拥有与函数完全相同的方法,例如在 Java 中,这将是等效的 addValues 函数。

public static int addValues( int x, int y ) {
    return x + y;
}

看起来很熟悉?那是因为 Java 的根源在于 C++,而 C++ 源于 C。

最后只是一个概念,在实现中它们可能看起来相同,但在 OO 文档中这些被称为方法。

这是 Java 中以前的 Employee 对象的示例。

public class Employee {

    Department department;
    String name;

    public String whatsYourName(){
        return this.name;
    }
    public String whatsYourDeparmentsName(){
         return this.department.name();
    }
    public String whatAreYouDoing(){
        return "nothing";
    } 
    // Ignore the following, only set here for completness
    public Employee( String name ) {
        this.name = name;
    }

}

// Usage sample.
Employee employee = new Employee( "John" ); // Creates an employee called John

// If I want to display what is this employee doing I could use its methods.
// to know it.
String name = employee.whatIsYourName():
String doingWhat = employee.whatAreYouDoint();

// Print the info to the console.

 System.out.printf("Employee %s is doing: %s", name, doingWhat );

Output:
Employee John is doing nothing.

那么,区别在于应用它的“域”。

AppleScript 有“自然语言”matphor 的想法,在某些时候 OO 有。例如 Smalltalk。我希望在阅读本文后,您可以更容易地理解对象中的方法。

注意:代码不编译,仅作为示例。随意修改帖子并添加 Python 示例。


T
TheSoftwareJedi

在 OO 世界中,这两者通常用于表示同一事物。

从纯数学和 CS 的角度来看,当使用相同的参数 ( f(x,y) = (x + y) ) 调用时,函数将始终返回相同的结果。另一方面,方法通常与类的实例相关联。尽管如此,大多数现代 OO 语言在大多数情况下不再使用术语“函数”。许多静态方法可能与函数非常相似,因为它们通常没有状态(并非总是如此)。


M
Mike Tunnicliffe

假设一个函数是一段代码(通常有自己的作用域,有时也有自己的闭包),它可以接收一些参数,也可以返回一个结果。

方法是一个对象拥有的函数(在一些面向对象的系统中,更正确的说法是它由一个类拥有)。被对象/类“拥有”意味着您通过对象/类引用方法;例如,在 Java 中,如果要调用对象“door”拥有的方法“open()”,则需要编写“door.open()”。

通常方法还会获得一些额外的属性来描述它们在对象/类中的行为,例如:可见性(与面向对象的封装概念相关),它定义了可以从哪些对象(或类)调用方法。

在许多面向对象的语言中,所有“函数”都属于某个对象(或类),因此在这些语言中没有不是方法的函数。


我强调方法可以由对象或类拥有,因为 Javascript(您在问题中提到)是一种语言,它通过拥有对象而不是类拥有方法(尽管与类存在)。
S
Statement

方法是类的函数。用普通的术语来说,人们到处交换方法和功能。基本上您可以将它们视为同一事物(不确定全局函数是否称为方法)。

http://en.wikipedia.org/wiki/Method_(computer_science)


B
Bradley Mazurek

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

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

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

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

因此,如果您有一个带有方法 g(x) 的对象 Z,您可能会看到以下内容:

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

在这种情况下,参数 x 被传入,与前面的函数示例相同。但是,cos() 的参数是存在于对象 Z 内部的值。Z 和存在于其中的数据 (Zy) 是 Z 的 g() 方法的隐式参数。


J
Jaimin Patel

从历史上看,“方法”是不返回值的东西,而“函数”是返回值的东西,这可能存在细微差别。每种语言都有自己的具有特殊含义的术语词典。

在“C”中,“函数”一词表示程序例程。

在 Java 中,术语“函数”没有任何特殊含义。而“方法”是指形成类实现的例程之一。

在 C# 中,这将翻译为:

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

但实际上,我重申这两个概念确实没有区别。如果您在有关 Java 的非正式讨论中使用术语“函数”,人们会认为您的意思是“方法”并继续。不要在有关 Java 的适当文档或演示文稿中使用它,否则你会看起来很傻。


实际上,在您的示例中,两者都是 method...或者我将其称为 procedurefunction
t
tshepang

函数或方法是一段命名的可调用代码,它执行一些操作并可选地返回一个值。

在 C 语言中,使用术语函数。 Java 和 C# 人们会说它是一种方法(在这种情况下,函数是在类/对象中定义的)。

C++ 程序员可能将其称为函数或有时方法(取决于他们是否正在编写过程风格的 C++ 代码或正在执行 C++ 的面向对象方式,只有 C/C++ 的程序员也可能将其称为函数,因为术语“方法”是在 C/C++ 文献中较少使用)。

您只需调用函数的名称即可使用函数,

result = mySum(num1, num2);

您可以通过首先引用其对象来调用方法,例如,

result = MyCalc.mySum(num1,num2);

佚名

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

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


非常漂亮和简洁的描述。
M
Mark Brittingham

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

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

最后——所以任何 Pascal 大师都不会在这里跳到我身上——Pascal 还区分了“函数”(返回值)和“过程”,后者没有。尽管您当然可以选择是否返回值,但 C# 并没有明确地做出这种区分。


S
Statement

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

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"
   }
}

S
Sam Stokes

既然您提到了 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)

(OO 纯粹主义者可能会争辩说方法与函数不同,如果您进入高级 Python 或 Ruby - 或 Smalltalk! - 您将开始明白他们的观点。此外,有些语言为方法提供了对对象的位的特殊访问权限。但是主要的概念差异仍然是隐藏的额外参数。)


D
Dirk Schumacher

对我来说:如果我同意,方法和函数的功能是相同的:

一个函数可以返回一个值

可能期望参数

就像任何一段代码一样,你可能有你放入的对象,你可能有一个对象作为结果。在这样做的过程中,他们可能会改变对象的状态,但这不会改变他们对我的基本功能。

在调用对象或其他代码的函数时可能存在定义差异。但这不就是语言上的区别,这就是人们交换它们的原因吗?我会小心提到的计算示例。因为我雇了员工来做我的计算:

new Employer().calculateSum( 8, 8 );

通过这样做,我可以依靠负责计算的雇主。如果他想要更多的钱,我会释放他,让碳素收集器处理闲置员工的功能来完成剩下的工作,并聘请一名新员工。

即使争论一个方法是一个对象函数而一个函数是非连接计算也无济于事。函数描述符本身以及理想情况下函数的文档将告诉我它需要什么以及它可能返回什么。其余的,比如操纵某个对象的状态对我来说并不是真正透明的。我确实希望函数和方法都能交付和操纵他们声称的内容,而无需详细了解他们是如何做到的。即使是纯计算函数也可能会更改控制台的状态或附加到日志文件。


S
SamyCode

让我们不要把应该是一个非常简单的答案复杂化。方法和函数是一回事。当函数在类外部时,您将其称为函数,而在将函数编写在类内部时,将其称为方法。


m
marcj

据我了解,方法是可以对类执行的任何操作。它是编程中使用的通用术语。

在许多语言中,方法由函数和子例程表示。大多数语言用于这些的主要区别是函数可能会将值返回给调用者,而子例程可能不会。然而,许多现代语言只有函数,但这些函数可以选择不返回任何值。

例如,假设您想描述一只猫,并且希望它能够打哈欠。您将创建一个带有 Yawn 方法的 Cat 类,它很可能是一个没有任何返回值的函数。


C
Captain Segfault

对于一阶近似,方法(在 C++ 风格的 OO 中)是成员函数的另一个词,即作为类的一部分的函数。

在像 C/C++ 这样的语言中,你可以拥有不是类成员的函数;您不会将与类无关的函数称为方法。


M
Morfidon

恕我直言,当人们想要引用对象内部的函数时,他们只是想发明一个新词来简化程序员之间的交流。

如果您说的是方法,那么您的意思是类中的函数。如果您说的是函数,那么您的意思只是类外的函数。

事实上,这两个词都是用来描述功能的。即使您错误地使用它,也不会发生任何错误。这两个词都很好地描述了您希望在代码中实现的目标。

函数是一个代码,它必须扮演做某事的角色(一个函数)。方法是解决问题的方法。

它做同样的事情。这是同样的事情。如果您想要超级精确并遵守约定,您可以将方法称为对象内部的函数。


A
Akshay Khale

函数是主要属于面向过程的编程的概念,其中函数是可以处理数据并返回值的实体

方法是面向对象编程的概念,其中方法是类的成员,主要对类成员进行处理。


t
tshepang

我不是专家,但这是我所知道的:

函数是C语言术语,它指的是一段代码,函数名将是使用该函数的标识符。方法是面向对象的术语,通常它在函数参数中有一个 this 指针。你不能像C那样调用这段代码,你需要使用对象来调用它。调用方法也不同。这里调用意思就是找到这段代码的地址。 C/C++,链接的时候会使用函数符号来定位。 Objective-C 是不同的。调用意思是一个 C 函数使用数据结构来查找地址。这意味着在运行时一切都是已知的。


y
yogendra saxena

TL;博士

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

函数示例:


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

方法示例:

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

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


f
f-society

我知道很多其他人已经回答了,但我发现以下是一个简单但有效的单行答案。虽然它看起来并不比这里的其他答案好很多,但如果你仔细阅读它,它会包含你需要了解的关于方法与功能的一切。

方法是具有定义接收器的函数,在 OOP 术语中,方法是对象实例上的函数。


S
Subrat Kumar Palhar

类是一些数据和函数的集合,可以选择使用构造函数。

当您创建该特定类的实例(复制、复制)时,构造函数会初始化该类并返回一个对象。

现在类成为对象(没有构造函数)&函数在对象上下文中被称为方法。

所以基本上

类<==新==>对象

函数<==新==>方法

在java中,通常被告知构造函数名称与类名称相同,但实际上构造函数类似于实例块和静态块,但具有用户定义的返回类型(即类类型)

而类可以有一个静态块,实例块,构造函数,函数对象通常只有数据和方法。


A
Aditya

函数 - 独立代码段中的函数,其中包含一些逻辑,必须独立调用并在类之外定义。

方法 - 方法是一段独立的代码,它在引用某个对象时被调用,并在类中定义。


静态类中的一段代码叫什么,也就是静态的,这是方法还是函数?类的静态函数/方法不需要声明它的类的对象。
L
Lance LI

在 C++ 中,有时使用方法来反映类的成员函数的概念。但是,最近我在《C++ 编程语言第 4 版》一书中的第 586 页“派生类”中找到了一条语句

虚函数有时也称为方法。

这有点令人困惑,但他有时会说,所以大致有道理,C++ 创建者倾向于将方法视为可以在对象上调用的函数,并且可以表现出多态性。


C
Community

以下是使用 JavaScript 示例对方法与函数的一些解释:

test(20, 50); 是函数定义,用于运行某些步骤或返回可以在某处存储/使用的内容。

您可以重用代码:定义一次代码并多次使用它。您可以使用不同的参数多次使用相同的代码,以产生不同的结果。

var x = myFunction(4, 3);   // Function is called, return value will end up in x

function myFunction(a, b) {
    return a * b;          // Function returns the product of a and b
}

var test = something.test(); 这里的 test() 可以是某个对象的方法,也可以是为内置对象自定义的原型,这里有更多解释:

JavaScript 方法是可以对对象执行的操作。 JavaScript 方法是包含函数定义的属性。

javascript中字符串的内置属性/方法:

var message = "Hello world!";
var x = message.toUpperCase();
//Output: HELLO WORLD!

自定义示例:

function person(firstName, lastName, age, eyeColor) {
    this.firstName = firstName;  
    this.lastName = lastName;
    this.age = age;
    this.eyeColor = eyeColor;
    this.changeName = function (name) {
        this.lastName = name;
    };
}

something.changeName("SomeName"); //This will change 'something' objject's name to 'SomeName'

您也可以为字符串、数组等定义属性,例如

String.prototype.distance = function (char) { var index = this.indexOf(char); if (index === -1) { console.log(char + " 没有出现在 " + this); } else { console.log(char + " is " + (this.length - index) + " 字符串末尾的字符!"); } }; var something = "ThisIsSomeString" // 现在像这样使用距离,运行并检查控制台日志 something.distance("m");

一些参考:Javascript Object MethodFunctionsMore info on prototype


请不要对多个问题发布相同的答案。发布一个好的答案,然后投票/标记以关闭其他问题作为重复问题。如果问题不是重复的,请调整您对该问题的答案。
感谢您的反馈,我没有定制其他答案,我删除了那个答案。 :-)