コンストラクタ デストラクタ

クラスとオブジェクト

 状態:  閲覧数:5,041  投稿日:2010-04-27  更新日:  
インスタンス(オブジェクト)生成時に自動実行される、クラスと同名の特殊なメンバ関数

※オブジェクト生成時に、自動的に、初めにコールされるだけの、メンバ関数(メソッド)の1つ



▼定義方法

・PHP5方式 - 「__construct()(アンダーライン2本で始まる)」

・PHP4方式 - 関数名をクラス名と同名(大文字小文字は区別されない)にする

ex.)クラス名 - 「AIR」、メンバ関数名(コンストラクタ) - 「AIR()」

※PHP4方式とPHP5方式の両方のコンストラクタが定義されていた場合は、PHP5方式がコールされる。



なお、PHP5より導入された「デストラクタ」定義方法は、「__destruct()(アンダーライン2本で始まる)」。



▼コールされるタイミング

・「コンストラクタ」 - 「new演算子」でオブジェクトが生成された時

・「デストラクタ」 - 生成されたオブジェクトが、どの変数からも参照されなくなった時



▼PHP4方式 例
 
class AIRPORT{
var $default;//メンバ変数は、必ずしも値を初期設定(値をセット)する必要はない
function AIRPORT(){//コンストラクタ
$this->default = "NARITA";//「メンバ変数$default」に「"NARITA"」がセット
}
function abroad(){//メンバ関数
echo $this->default;
}
}

$air = new AIRPORT;//オブジェクトを生成する際、殆どの場合「AIRPORT」後ろの「()(丸括弧)」を省略可能

$air->abroad();//メンバ関数の「abroad()」のみを実行

▼結果

  /demo/constructor1.html






▼コンストラクタの意義

クラス定義の際、メンバ変数に初期設定出来ない値でも、設定可能にする

※「var」を使ったメンバ変数の定義でセットできるのは定数のみで、定数以外のものをセットしたい場合は、コンストラクタ内でセットする。



クラス定義時におけるメンバ変数・設定可否値

・設定可能な値 - 定数「var $air = "AIR";」「var $signal = array("red", "blue", "yellow");」はセット可能。※「array()」は関数ではなく、言語構造

・設定不能な値 - 関数や演算子を利用しての値。「day $hode = date("Y/m/d H:i:s");」はセット不可。「var $time = 60 * 60 * 24;」といったものも(関数や演算子を使っているので)エラーとなる。また、「var $tokyo[] = "JAPAN";」のような書き方も不可。



▼コンストラクタに引数を渡す PHP4方式
 
class SIGNAL{
var $signal;//メンバ変数
function SIGNAL($arg = array()){//②引数1のコンストラクタ。受け取った配列を$argへ格納
$this->signal = $arg;//③$argへ格納した配列を、メンバ変数$signalへ格納
}
function check(){//⑤メンバ関数(メソッド)
echo "<pre>";
print_r($this->signal);//⑥メンバ変数$signalを、print_rする
echo "</pre>";
}
}
$signal = new SIGNAL(array("red", "blue", "yellow"));//①インスタンス作成。と同時にコンストラクタ実行。コンストラクタへ配列の引数を渡す
$signal->check();//④メンバ関数check実行

▼結果

  /demo/constructor_argument.html





▼PHP5 コンストラクタの定義。メソッド名を「__construct()」とするだけ。コンストラクタのアクセス修飾子は基本「public」に
<pre class="brush: php; collapse: true;">
<?php

class Product{
public function __construct(){//コンストラクタの定義。メソッド名を「__construct()」とするだけ。コンストラクタのアクセス修飾子は基本「public」に
}
}

?>
[/code]
▼結果(単にコンストラクタを定義しただけなので、結果には何も表示されない)

  /demo/constructor5_0_1.html





▼PHP5 一般的なコンストラクタ使用例
<pre class="brush: php; collapse: true;">
class Book{
private $name; // 商品名
private $publicationDate; // 出版日

// コンストラクタ(この例の場合、インスタンス生成時にただ一度だけ、値をセットする特殊なセッターのような使い方をしている。理由 ⇒ 出版日は、出版された時点で日付が決まり、後で変更されることがないため。例えば出版日を設定するためにpupublicなsetPublicationDateメソッドを作成してしまうと、いつでも自由に出版日を変更できてしまうことになる。また、プロパティ宣言時に初期値として「private $publicationDate = '20100608'」などと設定してしまうと全ての本の出版日が同じになってしまう)。要件を満たすクラスを実現するためには、外側よりの変更を一切出来なくしなければならないので、プロパティをprivateにし、設定用のメソッドも設定せず、コンストラクタを活用する。
public function __construct($name, $publicationDate){
$this->name= $name;
$this->publicationDate = $publicationDate;
}

// 商品名を取得(ゲッター)
public function getName(){
return $this->name;
}

// 出版日を取得(ゲッター)
public function getPublicationDate(){
return $this->publicationDate;
}
}

$book1 = new Book('PHPStyle', '2010/06/08');
$book2 = new Book('JavaScriptStyle', '2009/01/02');

$name1 = $book1->getName();
$date1 = $book1->getPublicationDate();
$name2 = $book2->getName();
$date2 = $book2->getPublicationDate();

print $name1 . 'は' . $date1 . 'に出版されました。';
print $name2 . 'は' . $date2 . 'に出版されました。';
[/code]
▼結果

  /demo/constructor5_0_2.html





▼その他

・オブジェクト生成時の、クラス名の後の「(丸括弧)」は省略出来る。コンストラクタに引数を渡す必要がない場合は書く必要がない。

・クラスを継承した場合、派生クラスのオブジェクトを生成・削除しても、基底クラスの「コンストラクタ」と「デストラクタ」は自動的にコールされないので、「parent::__construct()」や「parent::__destruct()」のように手動でコールする。



▼「コンストラクタ」&「デストラクタ」 PHP5方式
 
<pre>
<?php
class BASE{
protected function __construct(){//④
echo "○○ 基底クラスコンストラクタ BASE constructor 開始 ○○\n";
echo "○○ 基底クラスコンストラクタ BASE constructor 終了 ○○\n";
}
protected function __destruct(){//⑧
echo "×× 基底クラスデストラクタ BASE destructor 開始 ××\n";
echo "×× 基底クラスデストラクタ BASE destructor 終了 ××\n";
}
}

class SUB extends BASE{
public function __construct(){//②「コンストラクタ」がコールされる
echo "○○○ 派生クラスコンストラクタ SUB constructor 開始 ○○○\n";
parent::__construct();//③
echo "○○○ 派生クラスコンストラクタ SUB constructor 終了 ○○○\n\n";//⑤
}
public function __destruct(){//⑥
echo "××× 派生クラスデストラクタ SUB destructor 開始 ×××\n";
parent::__destruct();//⑦
echo "××× 派生クラスデストラクタ SUB destructor 終了 ×××\n\n";//⑨
}
}

class AIR{
private $id;
public function __construct($id){//⑪⑬⑯⑱⑳
$this->id = $id;
echo "→→→ AIR({$this->id}) constructor →→→\n\n";
}
public function __destruct(){//⑭
echo "←←← AIR({$this->id}) destructor ←←←\n\n";
}
}

echo 'new SUB;', "①オブジェクト生成(変数に代入しない)\n\n";
new SUB;//①オブジェクト生成(変数に代入しない)

$i = 0;

echo 'new AIR(0);', "⑩オブジェクト生成(変数へ代入)\n\n";
$air = new AIR($i++);//⑩オブジェクト生成(変数へ代入)

#オブジェクト生成
echo '>$air = new AIR(1);', "\n",//⑫
'>$air2 = new AIR(2);', "\n",
'>$air3 = new AIR(3);', "\n",
'>$air4 = new AIR(4);', "\n\n";
$air = new AIR($i++);//⑫
$air2 = new AIR($i++);//⑮
$air3 = new AIR($i++);//⑰
$air4 = new AIR($i++);//⑲

#アンセットする
echo '>unset($air3);', "\n\n";
unset($air3);//指定した変数を破棄

#「die()」でスクリプト終了。
die("************ Called die() ************\n\n");
?>
</pre>

▼結果

  /demo/constructor5.html






▼「デストラクタ」内の処理によってスクリプトが終了する場合、それ以降、別の「デストラクタ」はコールされない例
 
<pre>
<?php
class AIR{
private $id;
public function __construct($id){
$this->id = $id;
echo "○○○ AIR({$this->id}) constructor ○○○\n\n";
}
public function __destruct(){
echo "××× AIR({$this->id}) destructor ×××\n\n";
#未定義のメソッドをコールしてエラーを発生させる。
//$this->air();//Fatal error: Call to undefined method AIR::air()
}
}

$air1 = new AIR(1);
$air2 = new AIR(2);
$air3 = new AIR(3);

#未定義の関数をコールしてエラーを発生させる。
//air();// Fatal error: Call to undefined function air()
?>
</pre>

▼結果

  /demo/constructor5_1.html

Twitter検索結果。「コンストラクタ デストラクタ」に関する最新ツイート


「関数」「メンバ関数」「メソッド」違い

クラスの継承

コメント投稿(ログインが必要)



週間人気ページランキング / 5-28 → 6-3
順位 ページタイトル抜粋 アクセス数
1 ブラウザを閉じたらセッションデータはどうなるの? | セッション 34
2 Parse error: syntax error, unexpected 'public' (T_PUBLIC) | Parse error(エラーメッセージ) 14
3 スコープ | 変数 13
4 ブラウザを閉じたらセッションデータはどうなるの? | セッション 12
5 PHP用語 11
6 Fatal error: Access level to ▲::$△ must be protected (as in class ●) or weaker | Fatal error(エラーメッセージ) 9
7 セッションID | セッション 6
7 Fatal error: require_once(): Failed opening required 'PEAR.php' | Fatal error(エラーメッセージ) 6
7 コード例 … 「例外処理」はネストすることができる 6
7 Warning: include() [function.include]: Failed opening '**.php' for inclusion (in | Warning(エラーメッセージ) 6
7 セッション管理が必要な理由は、HTTPプロトコルには状態を保持する機能がないため | セッション 6
7 PHPで定数を定義する方法は2種類ある / 配列定数の定義 6
7 Fatal error: Call to undefined method MDB2_Error::execute() in ○○ on line △△ | Fatal error(エラーメッセージ) 6
8 型の種類 | 型 5
8 Fatal error: Uncaught RuntimeException: SplFileObject::__construct(): failed to open stream: Permission denied in | Fatal error(エラーメッセージ) 5
8 ガベージコレクション | 機能 5
9 curl で Cookie を使用する 4
9 @ | 演算子 4
9 ( ! ) Fatal error: Uncaught PDOException: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column | Fatal error(エラーメッセージ) 4
9 Warning: PDO::query(): LOAD DATA LOCAL INFILE forbidden | Warning(エラーメッセージ) 4
2023/6/4 1:01 更新