有人能简单解释OOP环境中的方法与函数吗?
“method”是“function”的面向对象词。这几乎就是它的全部(即,没有真正的区别)。
不幸的是,我认为这里的很多答案都在延续或推进一种观点,即存在一些复杂而有意义的差异。
真的-没有那么多,只是对同一件事用不同的词。
[后期添加]
事实上,正如BrianNeal在对这个问题的评论中指出的那样,C++标准在引用成员函数时从不使用“方法”一词。有些人可能认为这表明C++并不是真正的面向对象语言;然而,我更倾向于将其作为一种迹象,即一群相当聪明的人并不认为有特别强烈的理由使用不同的术语。
方法位于对象上或在类中是静态的。函数独立于任何对象(并且在任何类之外)。
对于Java和C#,只有方法。对于C,只有函数。
对于C++和Python,这取决于您是否在类中。但在基本英语中:
功能:独立功能。方法:做某事的一种方式,它有不同的方法或方法,但与同一方面(也称为类)相关。
方法是类的函数。用正常的术语来说,人们在各处交换方法和功能。基本上,您可以将它们视为相同的东西(不确定全局函数是否称为方法)。
http://en.wikipedia.org/wiki/Method_(计算机科学)
根据我的理解,方法是可以在类上执行的任何操作。它是编程中使用的通用术语。
在许多语言中,方法由函数和子程序表示。大多数语言用于这些的主要区别是,函数可能会返回一个值给调用者,而子程序可能不会。然而,许多现代语言只有函数,但这些函数可以选择不返回任何值。
例如,假设你想描述一只猫,你希望它能够打哈欠。您将使用Yawn方法创建一个Cat类,这很可能是一个没有任何返回值的函数。
假设函数是一个代码块(通常有自己的作用域,有时也有自己的闭包),它可以接收一些参数,也可以返回结果。
方法是由对象拥有的函数(在某些面向对象的系统中,更正确的说法是由类拥有)。被对象/类“拥有”意味着您通过对象/类引用方法;例如,在Java中,如果要调用对象“door”拥有的方法“open()”,则需要编写“door.open()”。
通常,方法还会获得一些额外的属性,描述它们在对象/类中的行为,例如:可见性(与面向对象的封装概念相关),它定义了可以从哪些对象(或类)调用方法。
在许多面向对象的语言中,所有的“函数”都属于某个对象(或类),因此在这些语言中没有不是方法的函数。
在OO世界中,这两个词通常用来表示同一件事。
从纯数学和CS的角度来看,当使用相同的参数(f(x,y)=(x+y))调用函数时,函数将始终返回相同的结果。另一方面,方法通常与类的实例相关联。尽管如此,大多数现代OO语言在很大程度上不再使用术语“函数”。许多静态方法可以很像函数,因为它们通常没有状态(不总是真的)。
类上的方法作用于类的实例,称为对象。
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"
}
}
在Object Pascal或C++等OO语言中,“方法”是与对象关联的函数。因此,例如,“狗”对象可能具有“吠叫”功能,这将被视为“方法”。相反,“StrLen”函数是独立的(它提供作为参数提供的字符串的长度)。因此,它只是一个“函数”。Javascript在技术上也是面向对象的,但与C++、C#或Pascal这样的成熟语言相比,它面临许多限制。尽管如此,这种区别仍然存在。
另外还有几个事实:C#是完全面向对象的,因此您无法创建独立的“函数”。在C#中,每个函数都绑定到一个对象,因此从技术上讲,都是一个“方法”。关键是,在C#中很少有人将它们称为“方法”-他们只是使用“函数”一词,因为没有任何真正的区别。
最后,为了让任何Pascal专家都不要跳到我这里,Pascal还区分了“函数”(返回值)和“过程”(不返回值)。C#并没有明确区分这一点,当然,您可以选择是否返回值。
对于一阶近似,方法(在C++风格的OO中)是成员函数的另一个词,即作为类一部分的函数。
在像C/C++这样的语言中,您可以使用不是类成员的函数;不能调用与类a方法无关的函数。
函数是一段按名称调用的代码。它可以传递数据以进行操作(即参数),也可以选择返回数据(返回值)。传递给函数的所有数据都是显式传递的。
方法是由与对象关联的名称调用的一段代码。在大多数方面,它与函数相同,但有两个关键区别:
方法隐式传递给调用它的对象。方法能够对包含在类中的数据进行操作(记住对象是类的实例-类是定义,对象是该数据的实例)。
(这是一个简化的解释,忽略了范围等问题)
面向对象范例背后的思想是“处理”软件由。。好的“对象”。现实世界中的对象具有财产,例如,如果您有一个Employee,则该员工具有姓名、员工id、职位、他属于某个部门等。
对象还知道如何处理其属性并对其执行一些操作。比方说,如果我们想知道员工现在在做什么,我们会问他。
employe whatAreYouDoing.
“whatAreYouDoing”是发送给对象的“消息”。对象知道如何回答这些问题,据说它有解决问题的“方法”。
因此,对象必须公开其行为的方式称为方法。因此,方法是工件对象必须“做”的事情。
其他可能的方法有
employee whatIsYourName
employee whatIsYourDepartmentsName
etc.
另一方面,函数是编程语言计算某些数据的方式,例如,您可以使用返回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;
}
说一个对象有一个“函数”来执行某些操作是不“自然”的,因为函数更多地与数学相关,而雇员几乎没有数学知识,但你可以有与函数完全相同的方法,例如在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示例。
一般来说:方法是属于类的函数,函数可以在代码的任何其他范围内,因此您可以声明所有方法都是函数,但不是所有函数都是方法:
以下面的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”是有意义的,因为人和狗都可以被喂养,你可以调用这个函数,因为它不属于任何特定的类。
函数是一个数学概念。例如:
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()方法的隐式参数。
既然您提到了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方法(使用“dot”语法,因为我在类中定义了它):
Greeter.greet(hello_greeter, "World")
所以我已经有效地将一个方法变成了一个函数。我能把函数变成方法吗?好吧,因为Python允许您在定义类之后处理它们,所以让我们尝试:
Greeter.greet2 = greet_with_greeter
hello_greeter.greet2("World")
是的,函数greet_with_greeter现在也称为方法greet2。这显示了方法和函数之间唯一真正的区别:当您通过调用object.method(args)“对”对象调用方法时,语言会神奇地将其转换为方法(object,args)。
(OO纯粹主义者可能会认为方法与函数不同,如果你进入高级Python或Ruby-或Smalltalk!-你会开始明白他们的观点。此外,一些语言赋予方法特殊的对象访问权限。但主要的概念区别仍然是隐藏的额外参数。)
函数是一组可以用来处理数据的逻辑。
而Method是一个用于处理其所属对象的数据的函数。因此,从技术上讲,如果您有一个与您的类不完全相关但在类中声明的函数,那么它不是一个方法;这被称为糟糕的设计。
为了我:如果我同意:
函数可以返回值可能需要参数
就像任何一段代码一样,你可能有你放入的对象,你可能会有一个作为结果出现的对象。在这样做的过程中,他们可能会改变对象的状态,但这不会改变他们对我的基本功能。
调用对象或其他代码的函数时可能存在定义差异。但这不就是语言差异的原因吗?这就是为什么人们会互换它们?上面提到的计算示例我会小心处理。因为我雇佣员工来计算:
new Employer().calculateSum( 8, 8 );
通过这样做,我可以依靠雇主负责计算。如果他想要更多的钱,我会让他自由,让碳水化合物收集者处理闲置员工的职能来完成剩下的工作,并雇佣一名新员工。
即使争论一个方法是一个对象函数,而一个函数是不相连的计算,这也无助于我。函数描述符本身以及理想的函数文档将告诉我它需要什么以及它可能返回什么。其余的,比如操纵某个对象的状态,对我来说并不是真正透明的。我确实希望函数和方法都能传递和操纵它们所声称的内容,而不需要详细了解它们是如何做到的。即使是纯计算函数也可能更改控制台的状态或附加到日志文件。
我不是专家,但我知道:
函数是C语言术语,它指的是一段代码,函数名将是使用此函数的标识符。方法是OO术语,通常它在函数参数中有一个this指针。您不能像C那样调用这段代码,您需要使用对象来调用它。调用方法也不同。这里调用含义来查找这段代码的地址。C/C++,链接时间将使用函数符号来定位。目标-C不同。调用表示使用数据结构查找地址的C函数。这意味着在运行时一切都是已知的。
函数或方法是一段命名的可调用代码,它执行一些操作并可选地返回一个值。
在C语言中,使用术语“函数”。Java和C#的人会说它是一个方法(在这种情况下,函数是在类/对象中定义的)。
C++程序员可能会将其称为函数或有时称为方法(取决于他们是在编写过程式C++代码还是以面向对象的方式使用C++,而且只有C/C++的程序员可能会称其为函数,因为C/C++文献中很少使用术语“方法”)。
你只需调用函数的名称,
result = mySum(num1, num2);
您可以通过首先引用其对象来调用方法,
result = MyCalc.mySum(num1,num2);
IMHO的人只是想发明一个新词,当他们想引用对象内部的函数时,可以更方便地在程序员之间进行交流。
如果你说的是方法,你指的是类内的函数。如果你说的是函数,那么你的意思只是类之外的函数。
事实上,这两个词都用来描述函数。即使你用错了,也不会发生任何错误。这两个词都很好地描述了您希望在代码中实现的目标。
函数是一个代码,它必须扮演一个做某事的角色(一个函数)。方法是解决问题的方法。
它也做同样的事情。这是同样的事情。如果你想超精确并遵循惯例,你可以调用方法作为对象内部的函数。
从历史上看,“方法”是不返回值的东西,而“函数”是返回值的,这两者之间可能存在着微妙的区别。每种语言都有自己的具有特殊含义的词汇。
在“C”中,“函数”一词表示程序例程。
在Java中,术语“函数”没有任何特殊含义。而“方法”是指构成类实现的例程之一。
在C#中,这可以翻译为:
public void DoSomething() {} // method
public int DoSomethingAndReturnMeANumber(){} // function
但实际上,我再次重申,这两个概念实际上没有什么不同。如果你在关于Java的非正式讨论中使用“函数”一词,人们会认为你的意思是“方法”并继续下去。不要在有关Java的适当文档或演示中使用它,否则你会看起来很傻。
我知道还有很多人已经回答了,但我发现以下是一个简单而有效的单行答案。虽然它看起来并没有比这里的其他答案好很多,但如果你仔细阅读它,它提供了你需要了解的关于方法与函数的一切。
方法是具有定义的接收器的函数,在OOP术语中,方法是对象实例上的函数。
在C++中,有时使用方法来反映类的成员函数的概念。然而,最近我在《C++编程语言第四版》一书中发现了一个声明,第586页“派生类”
虚函数有时称为方法。
这有点令人困惑,但他说,有时,C++创建者倾向于将方法视为可以在对象上调用的函数,并且可以表现为多态。
以下是使用JavaScript示例对方法与函数的一些解释:
测试(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、Array等定义财产
String.prototype.distance=函数(char){var index=this.indexOf(char);如果(索引==-1){console.log(char+“不出现在”+this中);}其他{console.log(char+“是”+(this.length-index)+“字符串末尾的字符!”);}};var something=“ThisIsSomeString”//现在像这样使用distance,运行并检查控制台日志距离(“m”);
一些参考:Javascript对象方法,函数,原型的更多信息
方法与功能的区别
在Microsoft上阅读此文档
包含可执行代码的成员统称为类的函数成员。上一节描述了方法,它们是函数成员的主要类型。本节介绍C#支持的其他类型的函数成员:构造函数、财产、索引器、事件、运算符和终结器。
所以方法是函数的子集。每个方法都是一个函数,但不是每个函数都是一种方法,例如,构造函数不能被称为方法,但它是一种函数。
类是一些数据和函数的集合,可以选择使用构造函数。
在创建该特定类的实例(副本、复制)时,构造函数初始化该类并返回一个对象。
现在类成为对象(没有构造函数)&函数在对象上下文中称为方法。
所以基本上
类<==new==>对象
函数<==new==>方法
在java中,构造函数的名称通常与类名相同,但实际上,构造函数类似于实例块和静态块,但具有用户定义的返回类型(即class类型)
而类可以具有静态块、实例块、构造函数、函数对象通常只有数据和方法。
它们通常是可互换的,但方法通常指类内的子例程,函数通常指类外的子例程。例如,在Ruby中:
# function
def putSqr(a)
puts a ** 2
end
class Math2
# method
def putSqr(a)
puts a ** 2
end
end
在Java中,所有内容(包和导入语句除外)都必须在类中,人们几乎总是将它们称为“方法”。
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)的语法糖。
如果不使用动态调度,仅此而已。如果使用了它,那么它就有点复杂了,但是编译器仍然会发出一个看起来像函数的东西,将其作为第一个参数。
方法和功能之间有明显的区别:
函数是一段独立的代码,您可以在任何地方调用它,只需在给定的参数中提及它的名称,就像在大多数过程语言(如C++和python)中一样。虽然
方法与对象具体相关,这意味着您只能在调用方法之前使用点(.)符号提及它的对象,就像在C#和java等纯面向对象语言中一样。
一般答案是:
方法具有对象上下文(this或类实例引用),
函数没有上下文(null、全局或静态)。
但问题的答案取决于你们使用的语言术语。
在JavaScript(ES6)中,您可以根据需要自定义函数上下文(this),通常必须链接到(this)对象实例上下文。在Java世界中,你总是听到“只有OOP类/对象,没有函数”,但如果你仔细观察Java中的静态方法,它们实际上是在全局/空上下文(或类的上下文,没有实例化)中,所以只有没有对象的函数。Java老师可以告诉你,函数是C++中C的雏形,在Java中已经过时了,但他们告诉你这是为了简化历史,避免新手提出不必要的问题。如果您在Java 7版本之后看到,您可以发现许多用于简化并行计算的纯函数编程元素(甚至不是来自C,而是来自1988年的Lisp),而且它不是OOP类风格。在C++和D世界中,事情变得更强大,您可以将函数和对象与方法和字段分开。但在实践中,您会再次看到没有this的函数和带有this的方法(带有对象上下文)。在FreePascal/Lazarus和BorlandPascal/Dephi中,函数和对象(变量和字段)的分离项通常与C++类似。Objective-C来自C世界,因此必须使用方法插件将C函数和Objective-C对象分开。C#与Java非常相似,但有许多C++的优点。
使用C#术语,函数和方法之间有区别。术语“函数成员”不仅包括方法,还包括其他非数据成员,如索引器、运算符、构造函数、析构函数和财产,所有成员都包含可执行代码。
reference=>专业C#和.NET 2021版-由Christina Nagel编写
方法和函数之间有什么区别?
Python的官方文档是这样定义的(感谢@Kelly Bundy!):
作用向调用者返回某个值的一系列语句。它还可以传递零个或多个参数,这些参数可以在主体的执行中使用。另请参阅参数、方法和函数定义部分
方法在类主体内定义的函数。如果作为该类实例的属性调用,该方法将获取实例对象作为其第一个参数(通常称为self)。请参见函数和嵌套范围。
正方形是矩形,但并非所有矩形都是正方形。我解释世界的方式是,一个方法是一个函数,但并不是所有的函数都是方法。方法之所以独特,是因为它是一种特殊类型的函数,它也与类关联,并且可以访问类成员变量。
另请参见:
hasattr被称为方法,但它看起来像函数
OOP是一种设计理念。在这种情况下,“方法”是一个“动作”,一个对象的“行为”,一种“操作”,是一个对象所做的事情。右键单击鼠标对象是一个动作。在实现OOP设计的几种语言中,这种行为被称为“方法”。“函数”仅与C和Pascal等过程语言相关,与OOP哲学无关,即使在技术上实现与方法类似。“函数”是程序语言(如C)中的一块代码,它有一个定义的目的,一个独立的和定义的功能,也可以返回结果。“过程”也是一个不返回结果的函数,但它只是技术上的区别。
函数是执行特定任务的一组指令或过程。它可以用来将代码分割成易于理解的部分,这些部分也可以被调用或重用。
方法是可以对对象执行的操作。它也称为存储为对象财产的函数。
主要区别:函数不需要任何对象并且是独立的,而方法是一个函数,它与任何对象链接。
//firstName() is the function
function firstName(){
cosole.log('John');
}
firstName() //Invoked without any object
const person = {
firstName: "John",
lastName: "Doe",
id: 5566,
};
//person.name is the method
person.name = function() {
return this.firstName + " " + this.lastName;
};
document.getElementById("demo").innerHTML =
"My father is " + person.name() //performs action on object;