方法和函数有什么区别?
有人可以在OOP上下文中提供方法与功能的简单说明吗?
解决方案
"方法"是"功能"的面向对象的单词。这几乎就是它的全部内容(即,没有真正的区别)。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
不幸的是,我认为这里的许多答案都在使或者存在着一些复杂的,有意义的差异的观念得以延续或者发展。
确实并没有那么多,针对同一件事只是不同的用词。
[后期补充]
实际上,正如Brian Neal在对此问题的评论中指出的那样,C ++标准在引用成员函数时从不使用术语"方法"。有人可能会认为这表明C ++并不是真正的面向对象的语言。但是,我更倾向于将其作为一种指示,即相当聪明的一群人认为没有特别强烈的理由使用另一个术语。
方法在对象上。
功能独立于对象。
对于Java,只有方法。
对于C,只有功能。
对于C ++,这取决于我们是否在课堂上。
方法是类的功能。用普通的术语来说,人们到处都是交换方法和功能。基本上,我们可以将它们视为同一事物(不确定全局函数是否称为方法)。
http://en.wikipedia.org/wiki/Method_(computer_science)
根据我的理解,方法是可以在类上执行的任何操作。它是编程中的通用术语。
在许多语言中,方法由函数和子例程表示。大多数语言为此使用的主要区别在于,函数可以将值返回给调用者,而子例程则不能。但是,许多现代语言仅具有函数,但是这些函数可以选择不返回任何值。
例如,假设我们想描述一只猫,并且希望它能打哈欠。我们将创建一个带有Yawn方法的Cat类,该类很可能是一个没有任何返回值的函数。
假设一个函数是一块代码块(通常具有自己的作用域,有时甚至具有自己的闭包),可以接收一些参数并且还可以返回结果。
方法是对象所拥有的功能(在某些面向对象的系统中,更确切地说它是类所拥有的)。被对象/类"拥有"意味着我们通过对象/类来引用该方法。例如,在Java中,如果要调用对象"门"拥有的方法" open()",则需要编写" door.open()"。
通常,方法还会获得一些额外的属性来描述它们在对象/类中的行为,例如:可见性(与封装的面向对象概念有关),它定义了可以从哪些对象(或者类)调用该方法。
在许多面向对象的语言中,所有"功能"都属于某个对象(或者类),因此在这些语言中,没有不属于方法的功能。
在OO世界中,两者通常用来表示同一件事。
从纯Math和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" } }
在诸如对象Pascal或者C ++之类的OO语言中,"方法"是与对象关联的功能。因此,例如,"狗"对象可能具有"吠叫"功能,因此将其视为"方法"。相反," StrLen"函数是单独存在的(它提供了作为参数提供的字符串的长度)。因此,它只是一个"功能"。从技术上讲,JavaScript也是面向对象的,但是与诸如C ++,Cor Pascal之类的成熟语言相比,JavaScript面临许多限制。尽管如此,区别仍然应保持。
还有两个事实:由于完全面向对象,因此我们无法创建独立的"函数"。在Cevery中,功能绑定到对象,因此从技术上讲,它是一种"方法"。更重要的是,在C语言中很少有人将它们称为"方法",而只是使用"功能"一词,因为没有任何真正的区别。
最后,只要任何Pascal专家都不会在这里碰到我,Pascal还会区分"函数"(返回值)和"过程"(不返回值)。尽管我们当然可以选择是否返回值,但是C并没有明确地进行区分。
对于一阶近似而言,方法(在C ++样式OO中)是成员函数的另一个词,该成员函数是类的一部分。
在像C / C ++这样的语言中,我们可以具有一些不是类成员的函数;这些函数不是类的成员。我们不会将与类无关的函数称为方法。
函数是按名称调用的一段代码。可以传递数据以对其进行操作(即参数),还可以选择返回数据(返回值)。传递给函数的所有数据都被显式传递。
方法是一段与对象关联的名称所调用的代码。在大多数方面,它与功能相同,但有两个主要区别:
- 方法被隐式传递给调用该方法的对象。
- 方法能够对类中包含的数据进行操作(记住,对象是类的实例-类是定义,对象是该数据的实例)。
(这是一个简化的说明,忽略了范围等问题。)
如果我们想在这里阅读"我对OO方法的介绍"
面向对象范例背后的思想是"威胁"该软件由..好"对象"组成。现实世界中的对象具有属性,例如,如果我们有一个Employee,该雇员具有姓名,雇员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; }
说一个对象具有执行某项操作的"功能"并不是"自然"的事情,因为功能与数学上的东西相关性更高,而雇员对数学的了解却很少,但是我们可以使用与功能完全相同的方法,例如在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具有"自然语言"的概念,这在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)),或者必须调用至少在python中的对象内部的方法(object.Method())。
将方法视为只有一个实体可以做的事情,因此,如果我们有一个Dog类,则仅在该类内部具有树皮函数是有意义的,那将是一种方法;如果我们也具有Person类,则对写一个不属于任何类别的函数" feed",因为人类和狗都可以被喂食,而我们可以调用该函数,因为它特别不属于任何类别。
函数是数学概念。例如:
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()方法的隐式参数。
自从我们提到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)
在对象上"调用"方法时,该语言神奇地将其转换为" method(object,args)"。
(OO纯粹主义者可能会认为方法与函数有所不同,如果我们使用高级Python或者Ruby或者Smalltalk!我们将开始明白他们的观点。某些语言还使方法可以对对象的某些位进行特殊访问。但是,主要概念上的差异仍然是隐藏的额外参数。)
函数是一组可用于处理数据的逻辑。
而Method是用于处理其所属对象的数据的函数。
因此从技术上讲,如果我们有一个与类不完全相关但在类中声明的函数,则它不是方法。这称为不良设计。