クラスベースのオブジェクト指向プログラミングにおいて、コンストラクタ(略称:ctor )は、オブジェクトを作成するために呼び出される特殊な関数です。コンストラクタは、新しいオブジェクトを使用できるように準備し、多くの場合、必要なメンバ変数を設定するために使用する引数を受け取ります。
コンストラクタはインスタンスメソッドに似ていますが、明示的な戻り値の型がなく、暗黙的に継承されず、スコープ修飾子に関する規則が異なる点でメソッドとは異なります。コンストラクタは宣言クラスと同じ名前を持つことがよくあります。オブジェクトのデータメンバを初期化し、クラスの不変条件を確立する役割を担い、不変条件が無効な場合は失敗します。適切に記述されたコンストラクタは、結果として得られるオブジェクトを有効な状態にします。不変オブジェクトはコンストラクタで初期化する必要があります。
ほとんどのプログラミング言語では、コンストラクタのオーバーロードが可能で、クラスごとに異なるパラメータを持つ複数のコンストラクタを設定できます。一部の言語では、特殊なタイプのコンストラクタを考慮しています。単一のクラスを使用してオブジェクトを作成し、そのクラスの新しいインスタンスを返すコンストラクタは、ファクトリによって抽象化されます。ファクトリもオブジェクトを作成しますが、複数のクラスを使用したり、オブジェクトプールなどの異なる割り当てスキームを使用したりするなど、さまざまな方法でオブジェクトを作成できます。
少なくとも1つの引数を取ることができるコンストラクタは、パラメータ付きコンストラクタと呼ばれます。パラメータ付きコンストラクタでオブジェクトを宣言する場合、初期値をコンストラクタ関数への引数として渡す必要があります。通常のオブジェクト宣言方法では動作しない場合があります。コンストラクタは明示的にも暗黙的にも呼び出すことができます。コンストラクタを暗黙的に呼び出す方法は、省略形メソッドとも呼ばれます。
class Point { private : int x ; int y ; public : Point () = default ; Point ( int x , int y ) : x { x }, y { y } {} // パラメータ付きコンストラクタ};Point p = Point ( 0 , 50 ); // 明示的な呼び出し。Point p2 ( 0 , 50 ); // 暗黙的な呼び出し。プログラマがインスタンス化可能なクラスのコンストラクタを提供しない場合、Java コンパイラはデフォルト コンストラクタをコードに挿入します。このコンストラクタはデフォルト コンストラクタとして知られています。コンパイル時にコードに挿入され、.classファイルに存在するため、ソース コード( .javaファイル) には存在しません。デフォルト コンストラクタの動作は言語に依存します。データ メンバーをゼロまたは他の同じ値で初期化する場合もあれば、何も行わない場合もあります。Java では、「デフォルト コンストラクタ」とは、クラスにコンストラクタが定義されていない場合、またはプログラマが定義したコンストラクタがない場合にコンパイラによって自動的に生成される nullary コンストラクタを指します (たとえば、Java では、デフォルト コンストラクタは暗黙的にスーパークラスのnullaryコンストラクタを呼び出し、空の本体を実行します)。すべてのフィールドは、初期値(整数型)、(浮動小数点型)、(ブール型)、(参照型) などに保持されます。00.0falsenull
class Point { private : int x ; int y ; public : Point ( int x = 0 , int y = 0 ); // デフォルトコンストラクタ。};C++ と同様に、Java も「コピー コンストラクタ」をサポートしています。ただし、C++ とは異なり、Java では、コピー コンストラクタが指定されていない場合でも、デフォルトのコピー コンストラクタは作成されません。コピー コンストラクタは、クラス オブジェクトをコピーする際にコンパイラが実行する動作を定義します。コピー コンストラクタには、クラスの型である仮引数が 1 つあります (引数はオブジェクトへの参照でも構いません)。これは、同じクラスの既存のオブジェクトのコピーを作成するために使用されます。両方のクラスが同じであっても、これは変換コンストラクタとして扱われます。コピー コンストラクタは通常、copy ctor または cctor と略されますが、.NETで同じ略語を使用するクラス コンストラクタとは何の関係もありません。
変換コンストラクタは、コンパイラが異なる型のオブジェクトに基づいて、あるクラスに属するオブジェクトを暗黙的に作成するための手段を提供する。これらのコンストラクタは通常、引数またはオペランドを適切な型に変換するために暗黙的に呼び出されるが、明示的に呼び出すこともできる。
C++では、ムーブコンストラクタはクラスのオブジェクトへの右辺値参照を受け取り、パラメータオブジェクトのリソースの所有権移転を実装するために使用されます。
new、fromなど)を含めることもできます。new。initializeコンパイラはnewメソッドを定義するため、ユーザーは を定義するだけで済みますinitialize。[ 1 ] Crystal コンパイラは自動的に定義しますが、ユーザーは を手動で定義しnewたり、デフォルトの使用を放棄してnew独自のコンストラクタを定義したりすることもできます。__construct場合は、クラスと同じ名前のメソッドが呼び出されます。PHP 5.3.3 以降、これは名前空間のないクラスでのみ機能します。 [ 2 ]__construct__construct。クラスと同じ名前のメソッドは、E_DEPRECATED レベルのエラーを引き起こします。[ 2 ]new) が自動的に作成され、BUILDメソッドを指定することで拡張されます。New" と呼ばれます。__new__" と " __init__" の 2 つのメソッドに分かれています。__new__メソッドはインスタンスのメモリ割り当てを担当し、クラスを引数として受け取ります (慣例的に " cls" と呼ばれます)。__init__メソッド (しばしば「初期化子」と呼ばれます) には、新しく作成されたインスタンスが引数として渡されます (慣例的に " self" と呼ばれます)。[ 3 ]constructor" で示され、ユーザー定義の名前を持つことができます (ただし、ほとんどの場合は " Create" と呼ばれます)。alloc" と " init" の2 つのメソッドに分割されています。allocメソッドはクラスのインスタンス用のメモリを確保(割り当て)し、initメソッドはインスタンスの初期化の大部分を処理します。メソッド " " を呼び出すと、クラス インスタンスに対して、メソッドとメソッドのnew両方が呼び出されます。allocinitJava、C#、およびVB.NETでは、コンストラクタはヒープ上に参照型オブジェクトを作成しますが、プリミティブ型(などint)はスタックdoubleに格納されます(ただし、一部の言語では修飾子を使用してスタック上にオブジェクトを手動で割り当てることができます)。VB.NETとC#では、演算子を使用して値型オブジェクトを作成することもできますが、これらの値型オブジェクトは、演算子の使用の有無にかかわらずスタック上に作成されます。これらの言語では、オブジェクトの破棄は、オブジェクトに参照がなくなり、ガベージコレクタによって破棄されたときに発生します。stackallocnew
C++では、コンストラクタが演算子なしで呼び出されるとオブジェクトはスタック上に作成されnew、演算子付きで呼び出されるとnew(オブジェクトへのポインタが返されます)、オブジェクトはヒープ上に作成されます。スタック上のオブジェクトはスコープ外になると暗黙的に削除されますが、ヒープ上のオブジェクトはデストラクタによって暗黙的に削除されるか、演算子を使用して明示的に削除する必要があります。「リソースの取得は初期化であるdelete」(RAII)イディオムを使用することで、リソース管理を大幅に簡素化できます。
コンストラクタは、さまざまなプログラミング言語で、以下のようなさまざまな方法で実装されています。
C言語にはコンストラクタは存在しません。しかし、コンストラクタと同様に、オブジェクトを作成する関数を定義することは可能です。
#include <stdlib.h>typedef struct { char * name ; int age ; } Person ;// このメソッドは Person のインスタンスを作成しますPerson * createPerson ( const char name [], int age ) { Person * p = ( Person * ) malloc ( sizeof ( Person )); if ( ! p ) { return NULL ; } strcpy ( p -> name , name ); p -> age = age ; return p ; }// このメソッドは Person のインスタンスを破棄しますvoid destroyPerson ( Person * p ) { if ( p ) { free ( p -> name ); free ( p ); } }C++では、コンストラクタの名前はクラス名と同じです。コンストラクタは何も返しません。メンバ関数と同様に、パラメータを持つことができます。コンストラクタ関数は通常publicセクションで宣言されますが、アクセスを制限したい場合はprotectedセクションやprivateセクションに宣言することもできます。
コンストラクタは 2 つの部分から構成されます。 1 つ目は、パラメータ リストの後に続き、メソッド本体の前に記述される初期化子リストです。これはコロンで始まり、エントリはカンマで区切られます。初期化子リストは必須ではありませんが、データ メンバーに値を指定し、個別の代入文を避けることができます。初期化子リストは、参照型のデータ メンバー、またはパラメータなしのコンストラクタ ロジックを持たないメンバーが存在する場合に必須です。代入は、データ メンバーが宣言された順序に従って実行されます (初期化子リストの順序が異なっていても)。[ 4 ] 2 つ目の部分は本体で、これは波括弧で囲まれた通常のメソッド本体です。一般的には、初期化子リストをできるだけ多く使用し、非代入操作や、初期化子リストを使用できない場合、または不十分な場合の代入にのみコンストラクタ本体を使用する方が、コストが安く、より良いプラクティスです。const
C++ では、複数のコンストラクタを使用できます。他のコンストラクタは、異なるパラメータを持つ必要があります。さらに、デフォルト値が与えられるパラメータを含むコンストラクタは、すべてのパラメータにデフォルト値が与えられていないという制約に従う必要があります。これは、デフォルト コンストラクタが存在する場合にのみ問題となる状況です。基底クラス(または複数の基底クラス) のコンストラクタは、派生クラスからも呼び出すことができます。コンストラクタ関数は継承されず、そのアドレスを参照することはできません。メモリ割り当てが必要な場合、newanddelete演算子は暗黙的に呼び出されます。
コピーコンストラクタは、参照として同じ型のパラメータを渡します。constたとえば、 です。明示的に指定されていない場合、コンパイラは各メンバ変数に対してコピーコンストラクタを使用するか、プリミティブ型の場合は単純に値をコピーします。デフォルトの実装は、クラスが動的にメンバ(または他のリソースへのハンドル)を割り当てている場合、破棄時に への二重呼び出し(またはリソースの二重解放)が発生する可能性があるため、効率的ではありません。X(constX&rhs)delete
import std ;class PolarPoint { private : double x ; double y ; public : explicit PolarPoint ( double r = 1.0 , double theta = 0.0 ) : // コンストラクタ、デフォルト値を持つパラメータ。x { r * std::cos ( theta ) }, y { r * std :: sin ( theta ) } /* <- 初期化リスト */ { std :: println ( "Point: x = {}, y = {}" , x , y ); // コンストラクタ本体} };呼び出し例:
PolarPoint a ;極点b ( 3 ); PolarPoint c ( 5 , std ::数値:: pi / 4 );関数からオブジェクトを返す場合、またはオブジェクトを値渡しする場合、戻り値の最適化が適用されない限り、オブジェクトのコピーコンストラクタが暗黙的に呼び出されます。
C++ は暗黙的にデフォルトのコピー コンストラクタを生成し、プログラマがコピー コンストラクタを指定するか、コピー コンストラクタを明示的に削除 (クローンを防ぐため)、またはコピー コンストラクタが削除されているかアクセスできない (プライベート) 場合を除き、すべての基底クラスとすべてのメンバ変数のコピー コンストラクタを呼び出します。カスタムコピー コンストラクタ(参照カウント、ポインタのディープ コピーなど) を必要とするほとんどのケースでは、デストラクタとコピー代入演算子もカスタマイズする必要があります。これは一般的に「 3 のルール」と呼ばれます。
C#のコンストラクターの例:
public class MyClass { private int a ; private string 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# 9.0 以降、ターゲットnew型式を使用することでコンストラクタ呼び出しをさらに簡略化できます。ターゲット型式では、型が既に指定されている場合、コンストラクタの名前を指定する必要がありません。変数の前に指定された型のコンストラクタが自動的に呼び出されますが、型推論 ( var) を使用している場合は当然解決されません。[ 5 ]
// 上記の例では、ターゲット型の新しい式を使用しています。MyClass c = new ( 42 , "string" );C#では、静的コンストラクタは静的データ初期化子です。[ 6 ] : 111–112静的コンストラクタはクラスコンストラクタ とも呼ばれます。実際に生成されるメソッドの名前が.cctorであるため、しばしば「cctor」とも呼ばれます。[ 7 ] [ 8 ]
静的コンストラクタは、複雑な静的変数の初期化を可能にします。[ 9 ] 静的コンストラクタは、クラスが最初にアクセスされたときに暗黙的に呼び出されます。クラスへの呼び出し(静的呼び出しまたはコンストラクタ呼び出し)は、静的コンストラクタの実行をトリガーします。静的コンストラクタはスレッドセーフであり、シングルトンパターンを実装します。汎用プログラミングクラスで使用される場合、静的コンストラクタは、新しい汎用インスタンス化ごとに型ごとに 1 回呼び出されます。[ 10 ] : 38 [ 6 ] : 111静的変数もインスタンス化されます。
public class MyClass { private static int _A ;// 通常のコンストラクタstatic MyClass () { _A = 32 ; }// 標準のデフォルトコンストラクタpublic MyClass () {} }// どこかにコード// 上記のコンストラクタを使用してオブジェクトをインスタンス化// インスタンス化の直前// 変数 static コンストラクタが実行され、_A は 32 になりますMyClass c = new MyClass ();ColdFusion Markup Languageinit (CFML) では、コンストラクタ メソッドとして「 」という名前のメソッドを使用します。
チーズ.cfc
コンポーネント{ // プロパティプロパティ名= "cheeseName" ;//コンストラクタ関数Cheese init (必須文字列cheeseName ) { variables.cheeseName = arguments.cheeseName ; return this ; } }チーズのインスタンスを作成します。
myCheese = new Cheese ( 'Cheddar' );ColdFusion 10以降、[ 11 ] CFMLではコンストラクタメソッドの名前を指定することもサポートされています。
component initmethod = "Cheese" { // プロパティproperty name = "cheeseName" ;//コンストラクタ関数Cheese Cheese (必須文字列cheeseName ) { variables.cheeseName = arguments.cheeseName ; return this ; } }Crystalでは、ユーザーがinitializeメソッドを定義し、コンパイラはそれを使用してnewオブジェクトのメモリを割り当て、ユーザー定義のメソッドを呼び出すメソッドを定義します。new必要に応じて、ユーザーは手動でメソッドを定義したり、別の名前で同等のメソッドを定義したりすることもできます(両方のコードinitializeをnew以下に示します)。このコードスニペットでは を定義していますがclass、Crystal の についても手順は同じですstruct。
class Car # 初期化子。インスタンスメソッドです。def initialize ( make : String , year : Int ) @make = make @year = year end # アロケータ。クラスメソッドで、「self.」プレフィックスで示されます。# `new` は `initialize` と同じ引数を取ることに注意してください。def self . new ( make : String , year : Int ) # インスタンスのメモリを割り当てます instance = Car . allocate #指定されたパラメータを使用してインスタンスの initialize メソッドを呼び出します instance . initialize make , year #インスタンスを返しますinstance end end# 次のように新しい `Car` をインスタンス化します: old_car = Car . new ( "Chevrolet" , 1947 )Eiffelでは、新しいオブジェクトを初期化するルーチンは作成プロシージャと呼ばれます。作成プロシージャには次の特性があります。
オブジェクトの作成にはいくつかの微妙な点がありますが、[ 12 ]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 ) do x := a_x_value y := a_y_value endx :実数-- X座標y :実数-- Y座標...2 番目のコードスニペットでは、クライアントであるクラスが、型のPOINT宣言my_point_1とを持っています。my_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()最初のステートメントである必要があります。[ 13 ]
class X { public X () { // パラメータなしコンストラクタthis ( 1 ); // コンストラクタの呼び出しSystem . out . println ( "デフォルトコンストラクタを呼び出しています" ); }public X ( int a ) { // パラメータ付きコンストラクタSystem . out . println ( "パラメータ付きコンストラクタを呼び出しています" ); } }public class Example { public static void main ( String [] args ) { X x = new X (); } }Javaでは、キーワードを通じてスーパークラスのコンストラクタにアクセスできますsuper。
class X { // インスタンス変数の宣言。private int data ;// コンストラクタの定義。public X () { this ( 1 ); }// コンストラクタのオーバーロードpublic X ( int input ) { data = input ; // これは代入です} }class Y extends X { private int data2 ;public Y () { super (); data2 = 1 ; }public Y ( int input1 , int input2 ) { super ( input1 ); data2 = input2 } }public class Example { public static void main ( String [] args ) { Y y = new Y ( 42 , 43 ); } }引数を取らないコンストラクタは、「引数なし」または「引数なし」コンストラクタと呼ばれます。[ 14 ]
ES6以降、JavaScriptは他の多くのプログラミング言語と同様に直接コンストラクタを備えています。それらは次のように記述されます。
class FooBar { constructor ( baz ) { this . baz = baz ; } }これは次のようにインスタンス化できます。
const foo = new FooBar ( '7' );ES6以前のこれに相当するものは、次のようなオブジェクトをインスタンス化する関数を作成することでした。
function FooBar ( baz ) { this . baz = baz ; }これは上記と同じ方法でインスタンス化されます。
これに相当するTypeScriptのコードは次のようになります。
class FooBar { baz : string ;constructor ( baz : string ) { this.baz = baz ; } }const foo : FooBar = new FooBar ( '7' );Object Pascalでは、コンストラクタはファクトリ メソッドに似ています。通常のメソッドとの構文上の違いは、constructor名前の前にキーワード (procedureまたはの代わりにfunction) が付いていることだけです。名前は任意ですが、慣例として、 をプレフィックスとして付けます。Createたとえば、 のようにCreateWithFormattingなります。クラスのインスタンスを作成する方法は、クラスの静的メソッドを呼び出すのと同様ですTPerson.Create('Peter')。
プログラムOopProgram ;type TPerson = class private FName : string ; public property Name : string read FName ; constructor Create ( AName : string ) ; end ;constructor 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オブジェクトが構築された直後に式を評価できます。[ 15 ]
class person first_name last_name = object val full_name = first_name ^ " " ^ last_nameinitializer print_endline ( "こんにちは、私は " ^ full_name ^ "です。" )メソッドget_last_name = last_name end ;;let alonzo = new person "Alonzo" "Church" in (*こんにちは、私はアロンゾ・チャーチです。*)print_endline alonzo # get_last_name (*Church*)PHPバージョン 5 以降では、コンストラクタは__construct()(二重アンダースコアであることに注意してください) という名前のメソッドであり、キーワードによってnewオブジェクトの作成後に自動的に呼び出されます。通常、プロパティの初期化などの初期化を自動的に実行するために使用されます。コンストラクタは引数も受け取ることができ、その場合はnewステートメントを記述する際に、パラメータとしてコンストラクタ引数も渡す必要があります。[ 2 ]
class Person { private string $name ;public function __construct ( string $name ) : void { $this -> name = $name ; }public function getName () : string { return $this- > name ; } }PHPでは、クラスが宣言できるコンストラクタメソッドは最大で1つだけです。静的メソッド、ファクトリクラス、またはオプションのコンストラクタ引数などは、PHPクラスのオブジェクトを作成するための複数の方法を可能にする手段です。
Perlバージョン 5では、デフォルトではコンストラクタはファクトリ メソッド、つまりオブジェクトを作成して返すメソッドであり、具体的には、有効な参照を作成して返すことを意味します。典型的なオブジェクトはハッシュへの参照ですが、まれに他の型への参照も使用されます。慣例として、コンストラクタは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 "Person->new() に必須属性がありません: first_name" ; } if ( not defined $self -> { last_name } ) { die "Person->new() に必須属性がありません: last_name" ; } if ( defined $self -> { age } and $self -> { age } < 18 ) { die "Person->new() の属性値が無効です: age < 18" ; }# Perl では 'bless' によってオブジェクトをクラスに所属させます。bless $self , $class ; return $self ; } 1 ;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歳未満はいないdie "18歳未満の方はおりません" ; } } 1 ;どちらの場合も、Personクラスは次のようにインスタンス化されます。
use Person ; my $p = Person- > new ( first_name => 'Sam' , last_name => 'Ashe' , age => 42 );Pythonでは、コンストラクタは と メソッドのいずれか、__new__または両方によって定義されます__init__。新しいインスタンスは、クラスを関数であるかのように呼び出すことによって作成され、その関数は__new__と__init__メソッドを呼び出します。クラスにコンストラクタ メソッドが定義されていない場合は、クラスのメソッド解決順序で次に見つかったメソッドが呼び出されます。[ 16 ]
通常は、__init__メソッドを定義するだけで十分です。(最も一般的な例外は、不変オブジェクトの場合です。)
class ExampleClass : def __new__ ( cls : type , value : int ) -> 'ExampleClass' : print ( "新しいインスタンスを作成しています..." ) # スーパークラスのコンストラクタを呼び出してインスタンスを作成します。instance : 'ExampleClass' = super ( ExampleClass , cls ) . __new__ ( cls ) return instancedef __init__ ( self , value : int ) -> None : print ( "インスタンスを初期化しています... " ) self.payload : int = valueif __name__ == "__main__" : exampleInstance : ExampleClass = ExampleClass ( 42 ) print ( exampleInstance . payload )これは以下を印刷します:
新しいインスタンスを作成しています... インスタンスを初期化しています... 42
クラスは通常、自身の新しいインスタンスを生成するファクトリとして機能します。つまり、クラスは呼び出し可能なオブジェクト(関数のようなもの)であり、呼び出しはコンストラクタであり、クラスを呼び出すと、そのクラスのインスタンスが返されます。ただし、__new__特殊な目的のために、メソッドがクラスのインスタンス以外のものを返すことが許可されています。その場合、は__init__呼び出されません。[ 16 ]
Rakuでは、デフォルトのnewメソッドが継承され、属性を指定でき、それらの属性が設定可能か、リセット可能か、必須かを指定できるため、さらに多くの定型コードを省略できます。さらに、カスタム初期化を可能にするために呼び出されるBUILDメソッドに、追加のコンストラクタ機能を含めることができます。TWEAKメソッドを指定することで、既に(暗黙的に)初期化された属性を後処理できます。
class Person { has Str $.first-name is required ; # 名 (文字列) は構築時にのみ設定できます (. は "public" を意味します)。has Str $.last-name is required ; # 姓 (文字列) は構築時にのみ設定できます(! は "private" を意味します)。has Int $.age is rw ; # 年齢 (整数) は構築後に変更できます('rw')。オブジェクトのインスタンス化時には必須ではありません。# 人のフルネームを返す 'full-name' メソッドを作成します。# このメソッドはクラスの外部からアクセスできます。method full-name { $!first-name . tc ~ " " ~ $!last-name . tc } # 年齢が設定されている場合は true を返す 'has-age' メソッドを作成します。# このメソッドはクラス内でのみ使用されるため、名前の前に ! method ! has-age { self . age . defined } # カスタム要件メソッドTWEAKをチェック{ if self ! has-age && $!age < 18 { # 18 歳未満の人はいませんdie "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 ではコロンとペアの構文を使用して名前付きパラメータを指定することもできます。
my $p0 = Person.new ( : first -name <Sam> , : last-name <Ashe> , : age ( 42 )); my $p1 = Person.new ( : first - name <Grace> , : last-name <Hopper> ); また、名前付きパラメータと同じ名前の変数を設定している場合は、名前付きパラメータに変数名を使用するショートカットを使用できます。
my $first-name = "Sam" ; my $last-name = "Ashe" ; my $age = 42 ; my $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>Rustにはオブジェクト指向プログラミングにおけるコンストラクタはありませんが、構造体にnew()はコンストラクタとして機能しうるメソッドがしばしば存在します。戻り値の型は通常、として示されますSelf。
struct Point { x : i32 , y : i32 , }impl Point { pub fn new ( x : i32 , y : i32 ) -> Self { Point { x , y } } }fn main ( ) { let p : Point = Point :: new ( 10 , 20 ); println! ( "Point is at ({}, {} ) " , p.x , p.y ) ; }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" )