私はクラスとオブジェクトクラスの構造を扱っていますが、複雑なレベルではありません。クラスと関数だけで、インスタンス化を1か所で行います。
__construct
および__destruct
、非常に簡単に教えてください:コンストラクタとデストラクタの目的は何ですか?
私は学校レベルの理論的説明を知っていますが、実際の世界のように、どの状況でそれらを使用しなければならないかを期待しています。
例も提供してください。
よろしく
コンストラクターは、オブジェクトが初期化された後に実行される関数です(割り当てられたメモリ、コピーされたインスタンスプロパティなど)。その目的は、オブジェクトを有効な状態にすることです。
多くの場合、オブジェクトが使用可能な状態になるには、何らかのデータが必要です。コンストラクタの目的は、インスタンス化時にこのデータをオブジェクトに強制的に与え、そのようなデータのないインスタンスを許可しないことです。
文字列をカプセル化し、この文字列の長さを返すメソッドを持つ単純なクラスを考えてください。 1つの可能な実装は次のとおりです。
class StringWrapper {
private $str;
public function setInnerString($str) {
$this->str = (string) $str;
}
public function getLength() {
if ($this->str === null)
throw new RuntimeException("Invalid state.");
return strlen($this->str);
}
}
有効な状態にするために、この関数はsetInnerString
の前にgetLength
を呼び出す必要があります。コンストラクタを使用すると、getLength
が呼び出されたときにすべてのインスタンスを強制的に良好な状態にすることができます。
class StringWrapper {
private $str;
public function __construct($str) {
$this->str = (string) $str;
}
public function getLength() {
return strlen($this->str);
}
}
setInnerString
を保持して、インスタンス化後に文字列を変更することもできます。
デストラクタは、オブジェクトがメモリから解放されるときに呼び出されます。通常、これにはクリーンアップコードが含まれます(たとえば、オブジェクトが保持しているファイル記述子のクローズ)。 PHPではまれです。なぜなら、PHPは、スクリプトの実行が終了すると、スクリプトが保持するすべてのリソースを消去するからです。
例で学ぶ:
class Person {
public $name;
public $surname;
public function __construct($name,$surname){
$this->name=$name;
$this->surname=$surname;
}
}
なぜこれが役立つのですか?代わりに:
$person = new Person();
$person->name='Christian';
$person->surname='Sciberras';
次を使用できます:
$person = new Person('Christian','Sciberras');
これはコードが少なく、きれいに見えます!
注:以下の応答が正しく述べているように、コンストラクター/デストラクターは、変数のデ/初期化(特に値が可変の場合)、メモリーのデ/割り当て、不変式(超過する可能性がある)、よりクリーンなコード。また、「よりクリーンなコード」は単なる「砂糖」ではなく、読みやすさ、保守性などを強化することにも注意してください。
コンストラクターは、クラスのインスタンスをインスタンス化するときに実行されます。クラスPerson
がある場合:
_class Person {
public $name = 'Bob'; // this is initialization
public $age;
public function __construct($name = '') {
if (!empty($name)) {
$this->name = $name;
}
}
public function introduce() {
echo "I'm {$this->name} and I'm {$this->age} years old\n";
}
public function __destruct() {
echo "Bye for now\n";
}
}
_
実証するには:
_$person = new Person;
$person->age = 20;
$person->introduce();
// I'm Bob and I'm 20 years old
// Bye for now
_
コンストラクター引数を使用して、初期化で設定されたデフォルト値をオーバーライドできます。
_$person = new Person('Fred');
$person->age = 20;
$person->introduce();
// if there are no other references to $person and
// unset($person) is called, the script ends
// or exit() is called __destruct() runs
unset($person);
// I'm Fred and I'm 20 years old
// Bye for now
_
コンストラクタとデストラクタが呼び出される場所、それらが何に役立つのかを実証するのに役立つことを願っています。
__construct()
は、リソースまたはより複雑なデータ構造を持つクラスメンバーをデフォルトにすることができます。__destruct()
は、ファイルハンドルやデータベースハンドルなどのリソースを解放できます。クラスのコンストラクターは、このクラスからオブジェクトをインスタンス化したときに何が起こるかを定義します。クラスのデストラクタは、オブジェクトインスタンスを破棄するときに何が起こるかを定義します。
コンストラクタとデストラクタに関するPHPマニュアル を参照してください。
PHP 5では、開発者がクラスのコンストラクターメソッドを宣言できます。コンストラクターメソッドを持つクラスは、新しく作成された各オブジェクトでこのメソッドを呼び出すため、オブジェクトが使用される前に必要な初期化に適しています。
そして
PHP 5では、C++などの他のオブジェクト指向言語のデストラクタの概念に似ています。特定のオブジェクトへのすべての参照が削除されるか、オブジェクトが明示的に破棄されるか、シャットダウンシーケンスの任意の順序でデストラクタメソッドが呼び出されます。
実際には、コンストラクタを使用して、オブジェクトを最小有効状態にします。つまり、コンストラクターに渡された引数をオブジェクトプロパティに割り当てます。オブジェクトがプロパティとして直接割り当てることができない何らかのデータ型を使用する場合、ここで作成します。
class Example
{
private $database;
private $storage;
public function __construct($database)
{
$this->database = $database;
$this->storage = new SplObjectStorage;
}
}
オブジェクトをテスト可能な状態に保つために、 コンストラクターは実際の作業を行うべきではありません :
共同作業者の作成/初期化、他のサービスとの通信、独自の状態を設定するロジックなどのコンストラクターでの作業は、テストに必要な継ぎ目を削除し、サブクラス/モックに不要な動作を継承させます。コンストラクターでの作業が多すぎると、テストでのインスタンス化やコラボレーターの変更が妨げられます。
上記のExample
では、$database
は共同編集者です。ライフサイクルと独自の目的があり、共有インスタンスの場合もあります。これをコンストラクター内で作成することはありません。一方、SplObjectStorage
はExample
の不可欠な部分です。ライフサイクルはまったく同じであり、他のオブジェクトとは共有されません。したがって、ctorでnew
itしてもかまいません。
同様に、デストラクタを使用してオブジェクトをクリーンアップします。ほとんどの場合、これはPHPによって自動的に処理されるため、不要です。これが、野生のdtorよりもはるかに多くのctorを見る理由です。
コンストラクタは、クラスのオブジェクトが作成されたときに自動的に実行されるクラスの関数です。そのコンストラクタを個別に呼び出す必要はありません。
コンストラクターの前にnew
キーワードについて考えたとき、把握するのが最も簡単であることがわかりました:呼び出すコンストラクターに基づいて、データ型の新しいオブジェクトが彼に与えられることを変数に単に伝えます私がそれに渡すものは、到着時にオブジェクトの状態に定義できます。
新しいオブジェクトがなければ、null
の土地に住んでいて、クラッシュします!
デストラクタは、C++の観点から最も明白であり、デストラクタメソッドで指定されたすべてのメモリを削除しないと、プログラムが終了した後も使用されたままになり、次の再起動までクライアントOSでリークとラグが発生します。
ここには十分な情報以上のものがあると確信していますが、私が気づいたことから別の角度が常に役立ちます!