クラスベースのオブジェクト指向プログラミングでは、コンストラクター(略称: ctor ) は、オブジェクトを作成するために呼び出される特殊なタイプの関数です。コンストラクターは、新しいオブジェクトを使用できるように準備し、多くの場合、コンストラクターが必要なメンバー変数を設定するために使用する引数を受け取ります。
コンストラクタはインスタンス メソッドに似ていますが、明示的な戻り値の型がなく、暗黙的に継承されず、スコープ修飾子のルールが通常異なるという点でメソッドとは異なります。コンストラクタは、宣言クラスと同じ名前を持つことがよくあります。コンストラクタには、オブジェクトのデータ メンバーを初期化し、クラスの不変式を確立するタスクがあり、不変式が無効な場合は失敗します。適切に記述されたコンストラクタは、結果のオブジェクトを有効な状態にします。不変オブジェクトは、コンストラクタで初期化する必要があります。
ほとんどの言語では、コンストラクターのオーバーロードが許可されており、クラスに対して、異なるパラメーターを持つ複数のコンストラクターが存在する可能性があります。一部の言語では、特別なタイプのコンストラクターが考慮されています。具体的には単一のクラスを使用してオブジェクトを作成し、クラスの新しいインスタンスを返すコンストラクターは、ファクトリーによって抽象化されます。ファクトリーもオブジェクトを作成しますが、複数のクラスやオブジェクト プールなどのさまざまな割り当てスキームを使用して、さまざまな方法で作成できます。
種類
パラメータ化されたコンストラクタ
少なくとも 1 つの引数を取ることができるコンストラクタは、パラメータ化されたコンストラクタと呼ばれます。オブジェクトがパラメータ化されたコンストラクタで宣言される場合、初期値はコンストラクタ関数に引数として渡される必要があります。通常のオブジェクト宣言の方法は機能しない可能性があります。コンストラクタは、明示的にも暗黙的にも呼び出すことができます。コンストラクタを暗黙的に呼び出す方法は、短縮法とも呼ばれます。
class Example { public : Example (); Example ( int a , int b ); // パラメータ化されたコンストラクター。
プライベート:
int x_ ; int y_ ; };
例::例() = default ;
例::例( int x , int y ) : x_ ( x ), y_ ( y ) {}
例e = Example ( 0 , 50 ); // 明示的な呼び出し。例e2 ( 0 , 50 ); // 暗黙的な呼び出し。
デフォルトコンストラクタ
プログラマがインスタンス化可能なクラスのコンストラクタを提供しない場合、Java コンパイラは、プログラマに代わってデフォルト コンストラクタをコードに挿入します。このコンストラクタは、デフォルト コンストラクタと呼ばれます。これは、コンパイル時にコードに挿入され、.class ファイルに存在するため、ソース コード (Java ファイル) には見つかりません。デフォルト コンストラクタの動作は言語に依存します。データ メンバーをゼロまたは他の同じ値に初期化することも、まったく何もしないこともあります。Java では、「デフォルト コンストラクタ」とは、クラスにコンストラクタが定義されていない場合、またはプログラマが定義したコンストラクタがない場合にコンパイラによって自動的に生成されるヌル引数コンストラクタを指します (たとえば、Java では、デフォルト コンストラクタはスーパークラスのヌル引数コンストラクタを暗黙的に呼び出し、空の本体を実行します)。すべてのフィールドは、初期値 0 (整数型)、0.0 (浮動小数点型)、false (ブール型)、または null (参照型) のままになります...
#include <iostream>
class Student { public : Student ( int a = 0 , int b = 0 ); // デフォルトのコンストラクター。
int a ; int b ; };
コピーコンストラクタ
C++ と同様に、Java も「コピー コンストラクター」をサポートしています。ただし、C++ とは異なり、Java では、独自のコピー コンストラクターを作成しない限り、デフォルトのコピー コンストラクターは作成されません。コピー コンストラクターは、クラス オブジェクトをコピーするときにコンパイラによって実行されるアクションを定義します。コピー コンストラクターには、クラスの型である 1 つの仮パラメータがあります (パラメータはオブジェクトへの参照の場合もあります)。これは、同じクラスの既存のオブジェクトのコピーを作成するために使用されます。両方のクラスが同じであっても、変換コンストラクターとしてカウントされます。コピー コンストラクターは通常、copy ctor または cctor と省略されますが、同じ省略形を使用して .NETで使用されるクラス コンストラクターとは何の関係もありません。
変換コンストラクタ
変換コンストラクタは、異なる型のオブジェクトに基づいて、あるクラスに属するオブジェクトをコンパイラが暗黙的に作成する手段を提供します。これらのコンストラクタは通常、引数またはオペランドを適切な型に変換するために暗黙的に呼び出されますが、明示的に呼び出されることもあります。
移動コンストラクタ
C++ では、移動コンストラクターはクラスのオブジェクトへの右辺値参照を受け取り、パラメーター オブジェクトのリソースの所有権の転送を実装するために使用されます。
構文
- Java、C++、C#、ActionScript、PHP 4、MATLABには、コンストラクターの名前が、関連付けられているクラスと同じ名前になるという命名規則があります。
- PHP 5では、コンストラクタの推奨名は です。下位互換性のため、メソッドが見つからない
__construct場合は、クラスと同じ名前のメソッドが呼び出されます。PHP 5.3.3以降、これは名前空間のないクラスでのみ機能します。 [1]__construct - PHP 7では、コンストラクタには常に という名前を付ける必要があります
__construct。クラスと同じ名前のメソッドは、E_DEPRECATEDレベルのエラーを引き起こします。[1] - Perlでは、慣例によりコンストラクタは「new」という名前が付けられ、かなりの量のオブジェクト作成を行う必要があります。
- Perl のMoose オブジェクト システムでは、コンストラクター ( newという名前) が自動的に作成され、 BUILDメソッドを指定することで拡張されます。
- Visual Basic .NETでは、コンストラクターは "
New" と呼ばれます。 - Pythonでは、コンストラクタは「
__new__」と「 」の2 つのメソッドに分割されます__init__。__new__メソッドはインスタンスのメモリを割り当てる役割を担い、クラスを引数として受け取ります (慣例的に「cls」と呼ばれます)。__init__メソッド (「初期化子」と呼ばれることが多い) には、新しく作成されたインスタンスが引数として渡されます (慣例的に「self」と呼ばれます)。[2] - Object Pascalコンストラクターはキーワード "
constructor" で示され、ユーザー定義の名前を持つことができます (ただし、ほとんどの場合は "Create" と呼ばれます)。 - Objective-Cでは、コンストラクタ メソッドは 2 つのメソッド "
alloc" と "init"に分割されalloc、メソッドはクラスのインスタンスのメモリを確保 (割り当て) し、initメソッドはインスタンスの初期化の大部分を処理します。メソッド " " を呼び出すと、クラス インスタンスのメソッドとメソッドのnew両方が呼び出されます。allocinit
記憶の組織化
Java、C#、および VB .NET では、コンストラクターは「ヒープ」と呼ばれる特別なメモリ構造に参照型オブジェクトを作成します。値型 (int、double など) は、「スタック」と呼ばれる連続構造に作成されます。VB .NET および C# では、new演算子を使用して値型オブジェクトを作成することもできますが、これらの値型オブジェクトは、演算子が使用されているかどうかに関係なく、スタック上に作成されます。
C++ では、コンストラクターが new 演算子なしで呼び出されるとオブジェクトはスタック上に作成され、コンストラクターが new 演算子付きで呼び出されるとヒープ上に作成されます。スタック オブジェクトはスコープ外になると暗黙的に削除されますが、ヒープ オブジェクトはデストラクタによって暗黙的に削除するか、delete演算子を使用して明示的に削除する必要があります。
言語の詳細
コンストラクターは、さまざまなプログラミング言語でさまざまな方法で実装されます。
C++
C++では、コンストラクタの名前はクラスの名前です。何も返しません。任意のメンバー関数と同様にパラメータを持つことができます。コンストラクタ関数は通常、パブリック セクションで宣言されますが、ユーザーがアクセスを制限したい場合は、プロテクト セクションとプライベート セクションで宣言することもできます。
コンストラクタには 2 つの部分があります。1 つ目は、パラメータ リストの後に続くメソッド本体の前にある初期化子リストです。これはコロンで始まり、エントリはコンマで区切られます。初期化子リストは必須ではありませんが、データ メンバーに値を提供して、別の割り当てステートメントを回避する機会を提供します。初期化子リストは、constまたは参照型のデータ メンバー、またはパラメータなしのコンストラクタ ロジックを持たないメンバーがある場合に必要です。割り当ては、データ メンバーが宣言された順序に従って行われます (初期化子リスト内の順序が異なっていても)。[3] 2 番目の部分は本体で、これは中括弧で囲まれた通常のメソッド本体です。
C++ では、複数のコンストラクタを使用できます。他のコンストラクタは、異なるパラメータを持つ必要があります。さらに、デフォルト値が与えられるパラメータを含むコンストラクタは、すべてのパラメータにデフォルト値が与えられるわけではないという制限に従う必要があります。これは、デフォルト コンストラクタがある場合にのみ問題となる状況です。基本クラス(または基本クラス) のコンストラクタは、派生クラスによって呼び出すこともできます。コンストラクタ関数は継承されず、そのアドレスは参照できません。メモリ割り当てが必要な場合、new演算子とdelete演算子が暗黙的に呼び出されます。
コピー コンストラクターには、同じ型のパラメーターがconst参照として渡されます (例: Vector(const Vector& rhs))。明示的に指定されていない場合、コンパイラーは各メンバー変数にコピー コンストラクターを使用するか、プリミティブ型の場合は単に値をコピーします。クラスに動的に割り当てられたメンバー (または他のリソースへのハンドル) がある場合、デフォルトの実装は効率的ではありません。破棄時に削除の二重呼び出し(またはリソースの二重解放) が発生する可能性があるためです。
class Foobar { public : Foobar ( double r = 1.0 , double alpha = 0.0 ) // コンストラクタ、デフォルト値を持つパラメータ。: x_ ( r * cos ( alpha )) // <- 初期化子リスト{ y_ = r * sin ( alpha ); // <- 通常の代入}
プライベート:
double x_ ; double y_ ; };
呼び出し例:
Foobar a 、b (3 )、c (5 、M_PI / 4 );
関数からオブジェクトを返す場合、またはオブジェクトを値で渡す場合、戻り値の最適化が適用されない限り、オブジェクトのコピー コンストラクターが暗黙的に呼び出されます。
C++ は、プログラマーがコピー コンストラクターを提供するか、コピー コンストラクターを明示的に削除するか (複製を防止するため)、またはいずれかの基本クラスまたはメンバー変数のコピー コンストラクターが削除されているかアクセスできない (プライベート) 場合を除き、すべての基本クラスとすべてのメンバー変数のコピー コンストラクターを呼び出すデフォルトのコピー コンストラクターを暗黙的に生成します。カスタマイズされたコピー コンストラクター(参照カウント、ポインターのディープ コピーなど) を呼び出すほとんどの場合、デストラクタとコピー代入演算子もカスタマイズする必要があります。これは一般に3 つのルールと呼ばれます。
C#
C#コンストラクターの例:
パブリッククラスMyClass {プライベートint a ;プライベート文字列b ;
// コンストラクター
public MyClass () : this ( 42 , "string" ) { }
// コンストラクターのオーバーロード
public MyClass ( int a , string b ) { this . a = a ; this . b = b ; } }
// どこかにコード
// 上記のコンストラクターを使用してオブジェクトをインスタンス化します
MyClass c = new MyClass ( 42 , "string" );
C# 静的コンストラクター
C#では、静的コンストラクタは静的データ初期化子です。[4] : 111–112 静的コンストラクタはクラスコンストラクタ とも呼ばれます。実際に生成されるメソッドの名前は.cctorであるため、「cctors」と呼ばれることもあります。[5] [6]
静的コンストラクターを使用すると、複雑な静的変数の初期化が可能になります。[7] 静的コンストラクターは、クラスが最初にアクセスされたときに暗黙的に呼び出されます。クラスへの呼び出し (静的またはコンストラクター呼び出し) はすべて、静的コンストラクターの実行をトリガーします。静的コンストラクターはスレッドセーフであり、シングルトンパターンを実装します。ジェネリックプログラミングクラスで使用する場合、静的コンストラクターは、新しいジェネリックインスタンス化ごとに、型ごとに1つずつ呼び出されます。[8] : 38 [4] : 111 静的変数もインスタンス化されます。
パブリッククラスMyClass {プライベート静的int _A ;
// 通常のコンストラクター
static MyClass () { _A = 32 ; }
// 標準のデフォルトコンストラクタ
public MyClass () {
}
}
// どこかのコード
// 上記のコンストラクターを使用してオブジェクトをインスタンス化します
// インスタンス化の直前
// 変数の静的コンストラクターが実行され、_A は 32 です
MyClass c = new MyClass ();
ColdFusion マークアップ言語 (CFML)
ColdFusion マークアップ言語init(CFML) は、コンストラクター メソッドとして
' ' という名前のメソッドを使用します。
チーズ.cfc
コンポーネント{ // プロパティproperty name = "cheeseName" ;
//
コンストラクター関数Cheese init ( required string cheeseName ) { variables.cheeseName = arguments.cheeseName ; return this ; } }
チーズのインスタンスを作成します。
myCheese =新しいCheese ( 'チェダー' );
ColdFusion 10以降、[9] CFMLではコンストラクタメソッドの名前の指定もサポートされています。
コンポーネントinitmethod = "Cheese" { // プロパティproperty name = "cheeseName" ;
//
コンストラクター関数Cheese Cheese ( required string cheeseName ) { variables.cheeseName = arguments.cheeseName ; return this ; } }
エッフェル
Eiffelでは、新しいオブジェクトを初期化するルーチンは作成プロシージャと呼ばれます。作成プロシージャには次の特性があります。
- 作成手順には明示的な戻り値の型はありません(手順の定義による)。[a]
- 作成手順に名前が付けられます。
- 作成手順は、クラスのテキスト内で作成手順として名前で指定されます。
- 作成プロシージャを明示的に呼び出して、既存のオブジェクトを再初期化できます。
- すべての有効な(つまり、具体的または非抽象的)クラスは、少なくとも 1 つの作成手順を指定する必要があります。
- 作成手順では、新しく初期化されたオブジェクトをクラス不変条件を満たす状態にしておく必要があります。[b]
オブジェクトの作成にはいくつかの微妙な点がありますが、[10]x: T作成命令で表現される典型的な宣言による属性の作成は、create x.make以下の一連の手順で構成されます。
- 型の新しい直接インスタンスを作成します
T。[c] make新しく作成されたインスタンスに対して作成手順を実行します。- 新しく初期化されたオブジェクトをエンティティにアタッチします
x。
以下の最初のスニペットでは、クラスPOINTが定義されています。プロシージャは、makeキーワードの後にコード化されていますfeature。
キーワードは、createインスタンスを初期化するために使用できるプロシージャのリストを導入します。この場合、リストにはdefault_create、クラス から継承された空の実装を持つプロシージャANY、およびmakeクラス内にコード化されたプロシージャが含まれます。
クラス
POINT作成default_create 、make
特徴
( a_x_value : REAL ; a_y_value : REAL )を実行し、 x := a_x_value y := a_y_valueとします。終了
x : REAL -- X座標
y : REAL -- Y座標...
2 番目のスニペットでは、 のクライアントであるクラスに、型のおよびのPOINT宣言があります。
my_point_1my_point_2POINT
手続き型コードでは、my_point_1は原点 (0.0, 0.0) として作成されます。作成手順が指定されていないため、default_createクラスから継承された手順ANYが使用されます。この行は とコード化することもできますcreate my_point_1.default_create。キーワードを含む命令では、作成手順として指定された手順のみを使用できますcreate。次は の作成命令でmy_point_2、 の座標の初期値を提供します。3 番目の命令は、 にアタッチされたインスタンスを異なる値で
再初期化するために、 プロシージャmy_point_2への通常のインスタンス呼び出しを行います。makemy_point_2
my_point_1 :ポイントmy_point_2 :ポイント...
my_point_1を作成します。my_point_2を作成します。( 3.0、4.0 ) my_point_2を作成します。( 5.0、8.0 ) ...
ファ#
F#では、コンストラクターにはクラスで定義されたステートメントletまたはステートメントを含めることができます。ステートメントはプライベート フィールドを定義し、ステートメントはコードを実行します。追加のコンストラクターは、キーワードを使用して定義できます。
doletdonew
type MyClass (_ a : int , _ b : string ) = class // プライマリコンストラクタlet a = _ a let b = _ b do printfn "a = %i, b = %s" a b
// 追加のコンストラクタ
new (_ a : int ) = MyClass (_ a , "" ) then printfn "整数パラメータが指定されました"
new (_ b : string ) = MyClass ( 0 , _ b ) then printfn "文字列パラメータが指定されました"
new () = MyClass ( 0 , "" ) then printfn "パラメータが指定されていません" end
// どこかのコード
// プライマリコンストラクタでオブジェクトをインスタンス化する
let c1 = new MyClass ( 42 , "string" )
// 追加のコンストラクタを使用してオブジェクトをインスタンス化する
let c2 = new MyClass ( 42 ) let c3 = new MyClass ( "string" ) let c4 = MyClass () // "new" キーワードはオプションです
ジャワ
Javaでは、コンストラクターは他のメソッドと次の点で異なります。
- コンストラクターには明示的な戻り値の型はありません。
- コンストラクターを直接呼び出すことはできません (キーワード「
new」で呼び出します)。 - コンストラクターには非アクセス修飾子を設定しないでください。
Java コンストラクターは、次のタスクを次の順序で実行します。
- コンストラクターが定義されていない場合は、スーパークラスのデフォルト コンストラクターを呼び出します。
- メンバー変数を指定された値に初期化します。
- コンストラクターの本体を実行します。
Javaでは、キーワードを使用して、あるコンストラクタを別のコンストラクタ内で呼び出すことができますthis()。ただし、this()最初のステートメントでなければなりません。[11]
class Example
{ Example () // 非パラメータ化コンストラクター{ this ( 1 ); //コンストラクターの呼び出しSystem.out.println ( " 0-arg-cons" ) ; } Example ( int a ) // パラメータ化コンストラクター{ System.out.println ( " 1 - arg-cons" ); } } public static void main ( String [ ] args ) { Example e = new Example ( ) ; }
Java では、キーワードを通じてスーパークラスのコンストラクターへのアクセスが提供されますsuper。
public class Example { // コンストラクターの定義。public Example ( ) { this ( 1 ); }
// コンストラクタのオーバーロード
public Example ( int input ) { data = input ; // これは代入です}
// インスタンス変数の宣言。
private int data ; }
// 他の場所にコード
// 上記のコンストラクターを使用してオブジェクトをインスタンス化する
Example e = new Example ( 42 );
引数を0個取るコンストラクタは「引数なし」または「引数なし」コンストラクタと呼ばれます。[12]
JavaScript
ES6では、JavaScriptは他の多くのプログラミング言語と同様に直接コンストラクタを持っています。それらは次のように記述されます。
クラスFooBar {コンストラクター( baz ) { this . baz = baz } }
これは次のように例証できる。
const foo =新しいFooBar ( '7' )
ES6以前では、これに相当するのは、オブジェクトを次のようにインスタンス化する関数を作成することでした。
関数FooBar ( baz ) { this . baz = baz ; }
これは上記と同じ方法でインスタンス化されます。
オブジェクトパスカル
Object Pascalでは、コンストラクタはファクトリ メソッドに似ています。通常のメソッドとの唯一の構文上の違いは、constructor名前の前にprocedureまたは ではなく というキーワードがあることです。コンストラクタには任意の名前を付けることができますが、慣例的には のように をプレフィックスとしてfunction付けます。クラスのインスタンスの作成は、クラスの静的メソッドの呼び出しと同じように機能します。
CreateCreateWithFormattingTPerson.Create('Peter')
プログラムOopProgram ;
type
TPerson = class private FName : string ; public property Name : string read FName ;コンストラクターCreate ( AName : string ) ; end ;
コンストラクターTPerson.Create ( AName : string ) ; begin FName : = AName ; end ;
var
Person : TPerson ; begin Person := TPerson . Create ( 'Peter' ) ; // TPerson のインスタンスを割り当て、パラメーター AName = 'Peter' を使用して TPerson.Create を呼び出しますend .
オカムル
OCamlにはコンストラクタが1つあります。パラメータはクラス名の直後に定義されます。パラメータはインスタンス変数を初期化するために使用でき、クラス全体からアクセスできます。匿名の隠しメソッドと呼ばれるメソッドを使用すると、initializerオブジェクトが構築された直後に式を評価できます。[13]
クラス person first_name last_name =
オブジェクト
val full_name = first_name ^ " " ^ last_name
初期化子
print_endline ( "こんにちは、私は " ^ full_name ^ " です。" )
メソッド get_last_name = last_name
終了;;
let alonzo = 新しい 人 「Alonzo」 「Church」 in (*こんにちは、私はAlonzo Churchです。*)
print_endline alonzo # get_last_name (*教会*)
PHP の
PHPバージョン 5 以降では、コンストラクタは__construct()(2 つのアンダースコアであることに注意) という名前のメソッドであり、キーワードによってnewオブジェクトの作成後に自動的に呼び出されます。これは通常、プロパティの初期化などの初期化を自動的に実行するために使用されます。コンストラクタは引数も受け取ることができます。その場合、newステートメントを記述するときに、パラメータのコンストラクタ引数も送信する必要があります。[1]
クラス Person
{
プライベート 文字列 $name ;
パブリック 関数 __construct (文字列 $name ) : void
{
$this -> name = $name ;
}
パブリック 関数 getName () : 文字列
{
return $this -> name ;
}
}
PHP では、クラスは最大 1 つのコンストラクター メソッドのみを宣言できます。静的メソッド、ファクトリ クラス、またはオプションのコンストラクター引数は、PHP クラスのオブジェクトを複数の方法で作成するための手段です。
パール5
Perlバージョン 5では、デフォルトでは、コンストラクタはファクトリ メソッド、つまりオブジェクトを作成して返すメソッド、具体的には、blessed 参照を作成して返すメソッドです。典型的なオブジェクトはハッシュへの参照ですが、他の型への参照もまれに使用されます。慣例により、唯一のコンストラクタの名前はnewですが、他の名前にしたり、複数のコンストラクタを持つことも許可されています。たとえば、Person クラスには、 newという名前のコンストラクタ、Person 属性のファイルを読み取るコンストラクタnew_from_file 、および別の Person オブジェクトをテンプレートとして使用するコンストラクタ new_from_personがあります。
package Person ; # Perl では、コンストラクターは慣例により 'new' と名付けられます。sub new { # クラス名は 0 番目の引数として暗黙的に渡されます。my $class = shift ;
# 属性値のデフォルト値(ある場合)。
my %defaults = ( foo => "bar" );
# 渡された引数とデフォルト値の組み合わせとして属性を初期化します。my
$ self = { %defaults , @_ };
# 必須の引数、クラス不変条件などをチェックします。
if ( not defined $self -> { first_name } ) { die "Mandatory attribute missing in Person->new(): first_name" ; } if ( not defined $self -> { last_name } ) { die "Mandatory attribute missing in Person->new(): last_name" ; } if ( defined $self -> { age } and $self -> { age } < 18 ) { die "Invalid attribute value in Person->new(): age < 18" ; }
# Perl は 'bless' によってオブジェクトをクラスに所属させます。
bless $self , $class ; return $self ; } 1 ;
Moose を使った Perl 5
Perl のMoose オブジェクト システムでは、この定型文のほとんどを省略でき、デフォルトのnewが作成され、属性を指定でき、属性が設定可能か、リセット可能か、必須かを指定できます。さらに、追加のコンストラクタ機能は、引数をチェックした後に Moose が生成したコンストラクタが呼び出すBUILDメソッドに含めることができます。ハッシュ参照 / キー => 値形式ではないコンストラクタ引数を処理するために、 BUILDARGSメソッドを指定できます。
package Person ; # Moose スタイルのオブジェクト構築を有効にするuse Moose ;
# ファースト ネーム (文字列) はコンストラクション時にのみ設定可能 ('ro')
has first_name => ( is => 'ro' , isa => 'Str' , required => 1 ); # ラスト ネーム (文字列) はコンストラクション時にのみ設定可能 ('ro') has last_name => ( is => 'ro' , isa => 'Str' , required => 1 ); # 年齢 (整数) はコンストラクション後に変更可能 ('rw') であり、コンストラクタに渡す必要はありません。また、年齢が設定されている場合は true を返す 'has_age' メソッドも作成しますhas age => ( is => 'rw' , isa => 'Int' , predicate => 'has_age' );
# カスタム要件を確認する
sub BUILD { my $self = shift ; if ( $self -> has_age && $self -> age < 18 ) { # 18 歳未満の人は死なない"No under-18 Persons" ; } } 1 ;
どちらの場合も、Person クラスは次のように初期化されます。
Personを使用します。my $ p = Person -> new ( first_name => 'Sam' 、last_name => 'Ashe' 、age => 42 );
パイソン
Pythonでは、コンストラクタは__new__とメソッドの一方または両方によって定義されます。新しいインスタンスは、とメソッド__init__を呼び出す関数であるかのようにクラスを呼び出すことによって作成されます。クラスでコンストラクタメソッドが定義されていない場合は、クラスのメソッド解決順序で次に見つかったメソッドが呼び出されます。[14]__new____init__
通常の場合、__init__メソッドのみを定義する必要があります。(最も一般的な例外は不変オブジェクトの場合です。)
>>> class ExampleClass :
... def __new__ ( cls , value ):
... print ( "新しいインスタンスを作成しています..." )
... # スーパークラスのコンストラクタを呼び出してインスタンスを作成します。
... instance = super ( ExampleClass , cls ) . __new__ ( cls )
... return instance
... def __init__ ( self , value ):
... print ( "インスタンスを初期化しています..." )
... self . payload = value
>>> exampleInstance = ExampleClass ( 42 )
新しいインスタンスを作成しています...
インスタンスを初期化しています...
>>> print ( exampleInstance . payload )
42
クラスは通常、自身の新しいインスタンスのファクトリーとして機能します。つまり、クラスは呼び出し可能なオブジェクト(関数など)であり、呼び出しはコンストラクタであり、クラスを呼び出すとそのクラスのインスタンスが返されます。ただし、メソッドは、__new__特殊な目的のためにクラスのインスタンス以外のものを返すことが許可されています。その場合、は__init__呼び出されません。[15]
楽
Rakuでは、デフォルトの新しいメソッドが継承され、属性を指定でき、属性が設定可能か、リセット可能か、必須かを指定できるため、さらに多くの定型句を省略できます。さらに、カスタム初期化を可能にするために呼び出されるBUILDメソッドに、追加のコンストラクター機能を含めることができます。TWEAK メソッドを指定して、すでに(暗黙的に)初期化されている属性を後処理できます。
class Person {
has Str $.first-nameは 必須です 。 # 名 (文字列) は構築時にのみ設定できます(. は「公開」を意味します)。 has Str $.last-nameは必須です。 # 姓 (文字列) は構築時にのみ設定できます(! は「非公開」を意味します)。 has Int $.ageはrwです。 # 年齢 (整数) は構築後 ('rw') に変更でき、オブジェクトのインスタンス化時には必要ありません。
# 人のフルネームを返す 'full-name' メソッドを作成します。
# このメソッドはクラス外からアクセスできます。
method full-name { $!first-name . tc ~ " " ~ $!last-name . tc }
# 年齢が設定されている場合は true を返す 'has-age' メソッドを作成します。
# このメソッドはクラス内でのみ使用されるため、
名前の先頭に !
method ! has-age { self . age . defined }を付けて "private" として宣言します。
# カスタム要件
メソッド TWEAKをチェックします{
if self ! has-age && $!age < 18 { # 18 歳未満の人は
死なない "18 歳未満の人は死なない" ;
}
}
}
Person クラスは次のようにインスタンス化されます。
my $p0 = Person . new ( first-name => 'Sam' , last-name => 'Ashe' , age => 42 );
my $p1 = Person . new ( first-name => 'grace' , last-name => 'hopper' );
say $p1 . full-name (); # 出力: «Grace Hopper»
あるいは、Perl 6 のコロンのペア構文を使用して 名前付きパラメータを指定することもできます。
私の $p0 = Person . new ( : first-name <Sam>、 : last-name <Ashe>、 : age ( 42 ) );
私の $p1 = Person . new ( : first-name <Grace>、 : last-name <Hopper> );
名前付きパラメータと同じ名前の変数を設定している場合は、名前付きパラメータに変数の 名前を使用するショートカットを使用できます。
私の $first-name = "Sam" ;
私の $last-name = "Ashe" ;
私の $age = 42 ;
私の $p0 = Person . new ( : $first-name , : $last-name , : $age );
ルビー
Rubyでは、 というメソッドを定義することでコンストラクタが作成されますinitialize。このメソッドは、新しいインスタンスをそれぞれ初期化するために実行されます。
irb(main):001:0> class ExampleClass irb(main):002:1> def initialize irb(main):003:2> puts "Hello there" irb(main):004:2> end irb(main):005:1> end => nil irb(main):006:0> ExampleClass . new Hello there => #<ExampleClass:0x007fb3f4299118>
ビジュアルベーシック
Visual Basic .NETでは、コンストラクターは " " という名前のメソッド宣言を使用しますNew。
クラスFoobarプライベートstrData As String
' コンストラクタ
Public Sub New ( ByVal someParam As String ) strData = someParam End Sub End Class
' 別の場所でコードを書く
' 上記のコンストラクタでオブジェクトをインスタンス化する
Dim foo As New Foobar ( ".NET" )
参照
- リソース取得は初期化です(RAII)
- 割り当て場所
- 創造パターン
- デストラクタ (コンピュータ プログラミング)
- C++のグローバルコンストラクタと、そのC版である((コンストラクタ))関数属性
注記
- ^ Eiffelルーチンは、プロシージャまたは関数のいずれかです。プロシージャには戻り値の型はありません。関数には常に戻り値の型があります。
- ^ 継承されたクラスの不変条件を満たす必要があるため、親のコンストラクターへの必須の呼び出しはありません。
- ^ Eiffel 標準では、最初のアクセス時にフィールドを初期化する必要があるため、オブジェクトの作成時にデフォルトのフィールド初期化を実行する必要はありません。
参考文献
- ^ abc コンストラクタとデストラクタ、PHP オンラインドキュメントより
- ^ データモデル、Python オンラインドキュメントより
- ^ https://stackoverflow.com/questions/1242830/constructor-initialization-list-evaluation-order コンストラクタ
- ^ アルバハリ、ジョセフ。C# 10 の概要。オライリー。ISBN 978-1-098-12195-2。
- ^ 「コーディングにおける素晴らしい冒険」。Eric Lippert。2013 年 2 月 6 日。2014 年 4 月 5 日閲覧。
- ^ エキスパート .NET 2.0 IL アセンブラ。 Aを押します。 2006年1月1日。ISBN 9781430202233. 2014年4月5日閲覧。
- ^ MSDN の C# の静的コンストラクター
- ^ スキート、ジョン。C #の詳細。マニング。ISBN 978-1617294532。
- ^ CFコンポーネント
- ^ エッフェル ISO/ECMA 仕様書
- ^ Javaのコンストラクタの詳細
- ^ 「クラスのコンストラクタの提供」。Oracle Corporation。2013 年。2013 年 12 月 20 日閲覧。
- ^ OCaml マニュアル
- ^ データモデル
- ^ データモデル
