オブジェクト指向プログラミング(OOP)におけるメソッドとは、オブジェクトに関連付けられた手続きであり、一般的にはメッセージも伴います。オブジェクトは状態データと動作から構成され、これらがインターフェースを形成し、オブジェクトの使用方法を規定します。メソッドは、ユーザーによってパラメータ化されたオブジェクトの動作です。
データはオブジェクトのプロパティとして表現され、動作はメソッドとして表現されます。例えば、オブジェクトにはやWindowといったメソッドがあり、その状態(特定の時点で開いているか閉じているか)はプロパティとなります。openclose
クラスベースのプログラミングでは、メソッドはクラス内で定義され、オブジェクトは特定のクラスのインスタンスです。メソッドが提供する最も重要な機能の 1 つは、メソッドのオーバーライドです。つまり、同じ名前 (例: ) を複数の異なる種類のクラスに使用できます。これにより、area送信オブジェクトは動作を呼び出し、それらの動作の実装を受信オブジェクトに委任できます。Java プログラミングのメソッドは、クラスオブジェクトの動作を設定します。たとえば、オブジェクトは別のオブジェクトにメッセージを送信でき、受信オブジェクトが、、などであっても、適切な式が呼び出されます。areaRectangleCircleTriangle
メソッドは、他のクラスがオブジェクトのプロパティにアクセスして変更するために使用するインターフェースも提供します。これはカプセル化として知られています。カプセル化とオーバーライドは、メソッドとプロシージャ呼び出しの主な違いです。[ 1 ]
メソッドのオーバーライドとオーバーロードは、メソッドが従来のプロシージャや関数呼び出しと異なる最も重要な方法の 2 つです。オーバーライドとは、サブクラスがスーパークラスのメソッドの実装を再定義することを指します。たとえば、findAreaシェイプ クラスで定義されたメソッドである場合、[ 2 ]Triangleなどは、それぞれその面積を計算するための適切な式を定義します。オブジェクトを「ブラックボックス」として扱うことで、オブジェクトの内部に変更を加えても、それを使用する他のオブジェクトへの影響を最小限に抑えることができます。これはカプセル化として知られており、コードの保守と再利用を容易にすることを目的としています。
一方、メソッドのオーバーロードとは、メソッドのパラメータに基づいてメッセージを処理するコードを区別することを指します。受信オブジェクトをメソッドの最初のパラメータとみなす場合、オーバーライドは、選択が最初の引数のみに基づいて行われるオーバーロードの特殊なケースと言えます。
アクセサメソッドは、オブジェクトのデータ値を読み取るために使用されます。ミューテータメソッドは、オブジェクトのデータを変更するために使用されます。マネージャメソッドは、クラスのオブジェクトを初期化および破棄するために使用されます(例:コンストラクタ、デストラクタ)。
これらのメソッドは、カプセル化とモジュール化を容易にする抽象化レイヤーを提供します。たとえば、銀行口座クラスが現在の残高を取得するアクセサメソッドを提供する場合(残高データフィールドに直接アクセスするのではなく)、同じコードの後の改訂版では、依存するコードを変更することなく、残高取得のためのより複雑なメカニズム(たとえば、データベースフェッチ)を実装できます。カプセル化とモジュール化の概念は、オブジェクト指向プログラミングに固有のものではありません。実際、多くの点で、オブジェクト指向アプローチは、抽象データ型や構造化プログラミングなどの以前のパラダイムの論理的な拡張にすぎません。[ 3 ]getBalance()
コンストラクタとは、オブジェクトのライフサイクルの開始時に呼び出され、オブジェクトを作成および初期化するメソッドです。このプロセスは構築(またはインスタンス化)と呼ばれます。初期化には、リソースの取得が含まれる場合があります。コンストラクタはパラメータを持つことができますが、ほとんどの言語では通常、値を返しません。Java の次の例を参照してください。
public class Person { private String name ; private int age ;// コンストラクタメソッドpublic Person ( String name , int age ) { this . name = name ; this . age = age ; } }デストラクタとは、オブジェクトのライフサイクルの終わりに自動的に呼び出されるメソッドであり、このプロセスは「破棄」と呼ばれます。ほとんどのプログラミング言語では、デストラクタメソッドは引数も戻り値も持ちません。デストラクタは、オブジェクト破棄時にクリーンアップ処理やその他のタスクを実行するように実装できます。
Java [ 4 ] : 26, 29、C# [ 5 ] : 208–209 、 Pythonなどのガベージコレクション言語では、デストラクタはファイナライザとして知られています。ファイナライザはデストラクタと同様の目的と機能を持っていますが、ガベージコレクションを利用する言語と手動メモリ管理を使用する言語との違いにより、呼び出される順序が異なります。
抽象メソッドとは、シグネチャのみを持ち、実装本体を持たないメソッドのことです。抽象クラスのように、サブクラスがメソッドの実装を提供する必要があることを指定する場合によく使用されます。一部のプログラミング言語では、抽象メソッドはインターフェースを指定するために使用されます。 [ 6 ]
![]()
以下のJavaコードは、拡張する必要のある抽象クラスを示しています。
abstract class Shape { // 抽象メソッドのシグネチャabstract int area ( int height , int width ); }以下のサブクラスはメインクラスを継承しています。
public class Rectangle extends Shape { @Override int area ( int height , int width ) { return height * width ; } }あるサブクラスが抽象メソッドの実装を提供している場合、別のサブクラスはそれを再び抽象メソッドにすることができます。これを再抽象化と呼びます。
実際には、これはほとんど使われない。
C#では、仮想メソッドを抽象メソッドでオーバーライドできます。(これはJavaにも当てはまり、Javaでは非プライベートメソッドはすべて仮想メソッドです。)
class IA { public virtual void M () { // ... } }abstract class IB : IA { // 許可されているpublic override abstract void M (); }インターフェースのデフォルトメソッドも再抽象化することができ、その場合、サブクラスがそれらを実装する必要があります。(これはJavaにも当てはまります。)
interface IA { void M () { // ... } }interface IB : IA { abstract void IA . M (); }// エラー: クラス 'C' は 'IA.M' を実装していません。class C : IB { // ... }クラスメソッドとは、インスタンスではなくクラスに対して呼び出されるメソッドです。これらは通常、オブジェクトメタモデルの一部として使用されます。つまり、メタモデルで定義された各クラスに対して、クラスオブジェクトのインスタンスが作成されます。 メタモデルプロトコルを使用すると、クラスの作成と削除が可能になります。この点では、前述のコンストラクタとデストラクタと同じ機能を提供します。ただし、Common Lisp Object System (CLOS)などの一部の言語では、メタモデルによって開発者は実行時にオブジェクトモデルを動的に変更できます。たとえば、新しいクラスの作成、クラス階層の再定義、プロパティの変更などが可能です。
特殊メソッドは言語固有のものであり、言語によってはここで定義されている特殊メソッドを全くサポートしない場合もあれば、一部をサポートする場合、あるいは全てをサポートする場合もあります。言語のコンパイラがデフォルトの特殊メソッドを自動的に生成する場合もあれば、プログラマが任意で特殊メソッドを定義できる場合もあります。ほとんどの特殊メソッドは直接呼び出すことはできませんが、コンパイラが適切なタイミングでそれらを呼び出すコードを生成します。
静的メソッドは、特定のインスタンスではなく、クラスのすべてのインスタンスに関連することを目的としています。その点では、静的変数と似ています。例えば、クラスのすべてのインスタンスのすべての変数の値を合計する静的メソッドが挙げられます。また、あるProductクラスに、すべての製品の平均価格を計算する静的メソッドを持たせることも可能です。
静的メソッドは、クラスのインスタンスがまだ存在しない場合でも呼び出すことができます。静的メソッドは、インスタンスメソッドのようにオブジェクトの実行時型に基づいて動的に解決されるのではなく、呼び出し元のクラスに基づいてコンパイル時に解決されるため、「静的」と呼ばれます。
Javaでは、よく使われる静的メソッドは ですMath.max()。
//呼び出し方: Math.max ( a , b ) ;// 次のように宣言されます: public class Math { // ...public static double max ( double a , double b ) { return ( a < b ) ? b : a ; } }この静的メソッドは所有オブジェクトを持たず、インスタンス上で実行されません。引数からすべての情報を受け取ります。[ 2 ]
コピー代入演算子は、クラスオブジェクトが同じ型のクラスオブジェクトに代入されたときにコンパイラが実行する動作を定義します。
演算子メソッドは、演算子シンボルを定義または再定義し、そのシンボルと関連付けられたメソッドパラメータを使用して実行される操作を定義します。C++ の例:
import std ;std :: stringを使用します。class Person { private : string name ; int age ; public : bool operator < ( const Person & other ) const { return age < other.age ; }bool operator == ( const Person & other ) const { return name == other . name && age == other . age ; } };一部の手続き型言語は、それらの言語の豊富なスキルセットとレガシーコードを活用しつつ、オブジェクト指向開発の利点も提供するために、オブジェクト指向機能で拡張されました。おそらく最もよく知られている例は、 Cプログラミング言語のオブジェクト指向拡張であるC++です。既存の手続き型言語にオブジェクト指向パラダイムを追加するという設計要件のため、C++ のメッセージパッシングには独自の機能と用語があります。たとえば、C++ ではメソッドはメンバ関数と呼ばれます。C++ には仮想関数の概念もあり、これは派生クラスでオーバーライドでき、動的ディスパッチを可能にするメンバ関数です。
仮想関数は、C++クラスがポリモーフィズムを実現するための手段です。非仮想メンバ関数、または通常のメソッドは、ポリモーフィズムに関与しません。
C++の例:
import std ;std :: unique_ptrを使用します。class Base { public : virtual ~ Base () = default ;virtual void getMessage () { std :: println ( "私はスーパークラスです!" ); } };class Derived : public Base { public : void getMessage () override { std :: println ( "私はサブクラスです!"); } };int main () { unique_ptr < Base > base = std :: make_unique < Base > (); unique_ptr < Base > derived = std :: make_unique < Derived > ();base- > getMessage (); // Base::getMessage() を呼び出します。derived- > getMessage (); // Derived::getMessage() を呼び出します。}