誰かがOOPコンテキストでのメソッドと関数の簡単な説明を提供できますか?
39 に答える
関数は、名前で呼び出されるコードです。操作対象のデータ (つまり、パラメーター) を渡すことができ、オプションでデータ (戻り値) を返すことができます。関数に渡されるすべてのデータは、明示的に渡されます。
メソッドは、オブジェクトに関連付けられた名前によって呼び出されるコードです。次の 2 つの重要な違いを除いて、ほとんどの点で関数と同じです。
- メソッドには、それが呼び出されたオブジェクトが暗黙的に渡されます。
- メソッドは、クラス内に含まれるデータを操作できます (オブジェクトはクラスのインスタンスであることを思い出してください。クラスは定義であり、オブジェクトはそのデータのインスタンスです)。
(これは単純化された説明であり、スコープの問題などを無視しています)
メソッドがオブジェクト上にあるか、クラス内で静的です。
関数は、どのオブジェクトにも依存しません (また、どのクラスにも依存しません)。
Java と C# の場合、メソッドしかありません。
C の場合は、関数しかありません。
C++ と Python の場合、クラスにいるかどうかによって異なります。
しかし、基本的な英語では:
- 機能: スタンドアロンの特徴または機能。
- メソッド: 何かを行うための 1 つの方法で、アプローチやメソッドは異なりますが、同じ側面 (別名クラス) に関連しています。
'method'は'function'のオブジェクト指向の単語です。それがほとんどすべてです (つまり、実際の違いはありません)。
残念ながら、ここでの回答の多くは、複雑で意味のある違いがあるという考えを永続させたり、前進させたりしていると思います。
本当に、それほど多くはありません。同じことを別の言葉で表現しているだけです。
【後期追加】
実際、Brian Nealがこの質問へのコメントで指摘したように、C++ 標準ではメンバー関数を参照するときに「メソッド」という用語は使用されません。一部の人々は、C++ が実際にはオブジェクト指向言語ではないことを示していると考えるかもしれません。しかし、私はそれを、非常に賢明な人々のグループが、別の用語を使用する特に強い理由があるとは考えていないことを示していると考えています.
一般に、メソッドはクラスに属する関数であり、関数はコードの他のスコープにある可能性があるため、すべてのメソッドが関数であると述べることができますが、すべての関数がメソッドであるとは限りません。
次の python の例を見てください。
class Door:
def open(self):
print 'hello stranger'
def knock_door:
a_door = Door()
Door.open(a_door)
knock_door()
与えられた例は、「open」というメソッドまたはアクションを持つ「Door」というクラスを示しています。クラス内で宣言されているため、メソッドと呼ばれます。関数を定義するコードのすぐ下に「def」が付いた別の部分があります。これはクラス内で宣言されていないため関数です。この関数は、ご覧のとおり、クラス内で定義したメソッドを呼び出し、最後に関数が実行されています。自ら呼んだ。
ご覧のとおり、どこでも関数を呼び出すことができますが、メソッドを呼び出す場合は、メソッドが宣言されているクラスと同じタイプの新しいオブジェクトを渡す必要があります (Class.method(object)) か、呼び出す必要があります。少なくとも Python では、オブジェクト内のメソッド (object.Method())。
メソッドは 1 つのエンティティのみが実行できるものと考えてください。そのため、Dog クラスがある場合、そのクラス内でのみ樹皮関数を使用することは理にかなっており、それはメソッドになります。Person クラスもある場合は、人間と犬の両方に餌を与えることができるため、どのクラスにも属さない関数「フィード」を記述します。特にどのクラスにも属さないため、それを関数と呼ぶことができます。
FunctionとMethodの主な違いの非常に一般的な定義:
関数はクラスの外部で定義されますが、メソッドはクラスの内部およびクラスの一部で定義されます。
読みたい方はこちら「私のOOメソッド入門」
オブジェクト指向パラダイムの背後にある考え方は、ソフトウェアが「オブジェクト」で構成されていることを「脅かす」ことです。実世界のオブジェクトにはプロパティがあります。たとえば、従業員がいる場合、従業員には名前、従業員 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 にあるためです。
最後にあるのは単なる概念です。実装では同じように見えるかもしれませんが、オブジェクト指向のドキュメントではこれらはメソッドと呼ばれます。
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 が持っていた「自然言語」 matphor のアイデアがあります。たとえば、Smalltalk。これを読んだ後、オブジェクトのメソッドを理解するのが合理的に簡単になることを願っています.
注: コードはコンパイルされません。例として役立つだけです。投稿を自由に変更して、Python の例を追加してください。
OO の世界では、この 2 つを同じ意味で使用するのが一般的です。
純粋な数学と CS の観点から、関数は同じ引数 ( f(x,y) = (x + y) ) で呼び出された場合、常に同じ結果を返します。一方、メソッドは通常、クラスのインスタンスに関連付けられています。繰り返しになりますが、最近のオブジェクト指向言語のほとんどは、「関数」という用語をほとんど使用していません。多くの静的メソッドは、通常は状態を持たないため (常に真であるとは限りません)、関数に非常によく似ています。
関数が、いくつかの引数を受け取り、結果を返す可能性があるコードのブロック (通常は独自のスコープを持ち、時には独自のクロージャを持つ) であるとしましょう。
メソッドは、オブジェクトが所有する関数です (一部のオブジェクト指向システムでは、クラスが所有していると言う方がより正確です)。オブジェクト/クラスによって「所有」されるということは、オブジェクト/クラスを通じてメソッドを参照することを意味します。たとえば、Java でオブジェクト「door」が所有するメソッド「open()」を呼び出したい場合は、「door.open()」と記述する必要があります。
通常、メソッドは、オブジェクト/クラス内での動作を説明する追加の属性も取得します。たとえば、可視性 (カプセル化のオブジェクト指向の概念に関連) は、メソッドを呼び出すことができるオブジェクト (またはクラス) を定義します。
多くのオブジェクト指向言語では、すべての「関数」は何らかのオブジェクト (またはクラス) に属しているため、これらの言語にはメソッドではない関数はありません。
メソッドはクラスの関数です。通常の専門用語では、人々はあらゆる方法と機能を交換します。基本的に、それらは同じものと考えることができます (グローバル関数がメソッドと呼ばれるかどうかはわかりません)。
関数は数学的な概念です。例えば:
f(x,y) = sin(x) + cos(y)
関数f()は、2番目のパラメーターのコサインに追加された最初のパラメーターのsinを返すことを示しています。それはただの数学です。たまたま、sin()とcos()も関数です。関数には別のプロパティがあります。同じパラメータを持つ関数へのすべての呼び出しは、同じ結果を返す必要があります。
一方、メソッドは、オブジェクト指向言語のオブジェクトに関連する関数です。これには、1つの暗黙的なパラメーターがあります。それは、作用を受けるオブジェクト(およびその状態)です。
したがって、メソッドg(x)を持つオブジェクトZがある場合、次のように表示される可能性があります。
Z.g(x) = sin(x) + cos(Z.y)
この場合、前の関数の例と同じように、パラメーターxが渡されます。ただし、cos()のパラメーターは、オブジェクトZの内部にある値です。Zとその内部にあるデータ(Zy)は、Zのg()メソッドの暗黙のパラメーターです。
歴史的に、値を返さない「メソッド」と値を返す「関数」という微妙な違いがあった可能性があります。各言語には、特別な意味を持つ独自の用語集があります。
「C」では、 「関数」という言葉はプログラムルーチンを意味します。
Javaでは、 「関数」という用語に特別な意味はありません。一方、 「メソッド」は、クラスの実装を形成するルーチンの 1 つを意味します。
C#では、次のように変換されます。
public void DoSomething() {} // method
public int DoSomethingAndReturnMeANumber(){} // function
しかし、実際には、2 つの概念に違いはないことを繰り返します。Java についての非公式な議論で「関数」という用語を使用すると、人々は「メソッド」を意味していると思い込んで続行します。Java に関する適切なドキュメントやプレゼンテーションで使用しないでください。ばかげているように見えます。
関数またはメソッドは、いくつかの操作を実行し、オプションで値を返す名前付きの呼び出し可能なコードです。
C言語では、関数という用語が使用されます。JavaとC#の人々はそれをメソッドと言うでしょう (この場合の関数はクラス/オブジェクト内で定義されます)。
C++プログラマーはそれを関数またはメソッドと呼ぶ場合があります (手続き型の C++ コードを書いているか、C++ のオブジェクト指向の方法を行っているかに応じて、C/C++ のみのプログラマーはそれを関数と呼ぶ可能性があります。C/C++ 文献ではあまり使用されません)。
次のように名前を呼び出すだけで関数を使用します。
result = mySum(num1, num2);
次のように、最初にそのオブジェクトを参照してメソッドを呼び出します。
result = MyCalc.mySum(num1,num2);
関数は、データを操作するために使用できるロジックのセットです。
一方、メソッドは、それが属するオブジェクトのデータを操作するために使用される関数です。したがって、技術的には、クラスに完全には関連していないが、クラスで宣言されている関数がある場合、それはメソッドではありません。それは悪いデザインと呼ばれています。
Object Pascal や C++ などのオブジェクト指向言語では、「メソッド」はオブジェクトに関連付けられた関数です。たとえば、「犬」オブジェクトには「吠える」機能があり、これは「メソッド」と見なされます。対照的に、「StrLen」関数はスタンドアロンです (引数として提供される文字列の長さを提供します)。したがって、それは単なる「関数」です。Javascript も技術的にはオブジェクト指向ですが、C++、C#、Pascal などの本格的な言語と比較して多くの制限があります。それにもかかわらず、区別は依然として保持されるべきです。
C# は完全にオブジェクト指向であるため、スタンドアロンの "関数" を作成することはできません。C# では、すべての関数がオブジェクトにバインドされているため、技術的には "メソッド" です。キッカーは、C# でそれらを「メソッド」と呼ぶ人はほとんどいないということです。彼らは単に「関数」という用語を使用しています。実際に区別する必要がないからです。
最後に - Pascal の達人がここで私に飛びつかないように - Pascal は "関数" (値を返す) とそうでない "手続き" も区別します。もちろん、値を返すかどうかを選択することはできますが、C# はこの区別を明示的に行いません。
クラスのメソッドは、オブジェクトと呼ばれるクラスのインスタンスに作用します。
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"
}
}
あなたが 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を使用するのとまったく同じ方法でメソッドを使用できgreet_with_greeterます (クラス内で定義したため、「ドット」構文を使用して取得します)。
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! に慣れれば、彼らの要点が見え始めるでしょう。また、いくつかの言語では、オブジェクトのビットへの特別なアクセスをメソッドに与えます。しかし、主な概念上の違いは、隠れた追加パラメーターです)。
私にとっては、次のことに同意すれば、メソッドと関数の機能は同じです。
- 関数は値を返す場合があります
- パラメータが必要な場合があります
他のコードと同じように、オブジェクトを挿入したり、結果としてオブジェクトを作成したりできます。そうしている間、彼らはオブジェクトの状態を変えるかもしれませんが、それは私にとっての基本的な機能を変えることはありません.
オブジェクトの関数や他のコードの呼び出しには定義の違いがあるかもしれません。しかし、それは言葉の区別のためのものであり、それが人々がそれらを交換する理由です. 私が注意する計算の例に言及しています。計算を行うために従業員を雇うからです。
new Employer().calculateSum( 8, 8 );
そうすることで、雇用主に計算の責任を負わせることができます。彼がより多くのお金を欲しがっている場合、私は彼を解放し、使用されていない従業員を処分する炭水化物コレクターの機能に残りを任せて、新しい従業員を獲得します.
メソッドはオブジェクト関数であり、関数は接続されていない計算であると主張しても、私には役に立ちません。関数記述子自体と、理想的には関数のドキュメントで、必要なものと返されるものがわかります。オブジェクトの状態を操作するなどの残りの部分は、私にとっては透過的ではありません。関数とメソッドの両方が、それがどのように行われるかを詳細に知る必要なく、主張するものを提供および操作することを期待しています。純粋な計算関数でさえ、コンソールの状態を変更したり、ログファイルに追加したりする可能性があります。
私の理解では、メソッドはクラスに対して実行できる操作です。プログラミングで使われる一般的な用語です。
多くの言語では、メソッドは関数とサブルーチンによって表されます。ほとんどの言語がこれらに使用する主な違いは、関数は呼び出し元に値を返す場合があり、サブルーチンは返さない場合があるということです。ただし、多くの現代言語には関数しかありませんが、これらはオプションで値を返さない場合があります。
たとえば、猫を説明したくて、あくびをできるようにしたいとしましょう。Yawn メソッドを使用して Cat クラスを作成しますが、これはおそらく戻り値のない関数です。
一次近似では、メソッド (C++ スタイルのオブジェクト指向) は、クラスの一部である関数であるメンバー関数の別の言葉です。
C/C++ のような言語では、クラスのメンバーではない関数を持つことができます。クラスに関連付けられていない関数をメソッドとは呼びません。
関数は、関数がデータを処理して値を返すことができるエンティティであるプロシージャ指向プログラミングに主に属する概念です。
メソッドはオブジェクト指向プログラミングの概念であり、メソッドは主にクラスメンバーで処理を行うクラスのメンバーです。