建構方法和析構方法是物件中的兩個特殊方法,它們都與物件的生命週期有關。建構方法是物件建立完成後第一個被物件自動呼叫的方法,這也是我們在物件中使用建構方法的原因。而析構方法是物件在銷毀之前最後一個被物件自動呼叫的方法,這也是我們在物件中使用析構方法的原因。所以通常使用建構方法完成一些物件的初始化工作,使用析構方法完成一些物件在銷毀之前的清理工作#。
在每個宣告的類別中都有一個嗆稱為建構方法的特殊成員方法,如果沒有明確的聲明它,類別中都會預設存在一個沒有參數列表並且內容為空的建構方法。如果明確的聲明它,則類別中的預設建構方法將不會存在。當建立物件時,建構方法就會被自動呼叫一次,也就是每次使用關鍵字new來實例化物件時都會自動呼叫建構方法,不能主動透過物件的參考呼叫建構方法。所以通常使用構造方法來執行一些有用的初始化任務,例如對成員屬性在創建物件時賦初值等。
在PHP5先前的版本中,建構方法的方法名稱必須與類別名稱相同,這種方式在PHP 5中任然可以使用。但在PHP中很少宣告和類別名稱同名的建構方法了,這樣做的好處是可以使建構子獨立於類別名,當類別名稱改變時不需要改變對應的建構子名稱。為了向下相容,在建立物件時,如果一個類別中沒有名為construct()的建構方法,PHP將搜尋與類別名稱相同名的建構方法執行。在類別中宣告建構方法的格式如下:
function construct( [参数列表] ){ //构造方法名称是以两个下划线开始的 //方法体,通常用来对成员属性进行初始化赋值}
在PHP中,同一個類別中只能宣告一個建構方法。原因是建構方法名稱是固定的,在PHP中不能宣告同名的兩個函數,所以也就沒有建構方法重載。但可以在宣告建構方法時使用預設參數,實作其他物件導向的程式語言中建構方法重載的功能。這樣在建立物件時,如果在建構方法中沒有傳入參數,則使用預設參數為成員屬性進行初始化。
建構子可以接受參數,能夠在建立物件時賦值給物件屬性
建構子可以呼叫類別方法或其他函數
建構子可以呼叫其他類別的建構子
建構子使用範例:
<?phpclass Person{ private $name; private $age; private $gender; public function construct($name,$age,$gender){ $this->setName($name); //调用类方法 $this->age = $age; $this->setGender($gender); } public function setName($name){ $this->name = $name; } // ... setter 方法}$person = new Person("yeoman",23,'男');?>
呼叫父類別建構子、呼叫無關類別的建構子:
function construct(){ parent::construct(); // 调用父类的构造函数必须显示的使用parent调用父类构造函数 classname::construct(); // 调用其他类的构造函数,classname是类名 //其他操作}
繼承與建構子
PHP中的子類別的建構子不會主動呼叫父類別的建構函數,要顯示的使用parent::construct()呼叫:
<?php class Animal{ private $name; function construct($name){ $this->setName($name) echo "动物类被创建!"; } // ... 其他方法}class Birds extends Animal{ private $name; private $leg; function construct($name,$leg){ parent::construct($name); // 显示调用 $this->setLeg($leg); echo "鸟类被创建!"; } // ... 其他方法}?>
如果涉及多層繼承,當呼叫parent::construct()時,會沿著父類別向上搜索,直到找到最合適的建構函數,例如:
// 接上例class Parrot extends Birds{ private $name; private $leg; private $wing; function construct($name){ parent::construct($name); // 此时没有找到父类(Birds类)合适的构造函数,只能向上搜索,搜索到Animal类时,才找到合适的构造函数 echo "鹦鹉类被创建!"; $this->smackTalk(); /* 输出结果: "动物类被创建!" "鹦鹉说话!" */ } function smackTalk(){ echo "鹦鹉说话!"; } }
如果想要依序呼叫幾個父類別的建構函數,可以使用類別名稱直接呼叫建構函數,例如:
function construct($name,$leg){ Animal::construct($name); // 调用Animal构造函数 Birds::construct($name,$leg); // 调用Birds构造函数}
析構方法允許在銷毀一個物件之前執行一些特定的操作,例如關閉文件,釋放結果集等。
當堆記憶體段中的物件失去存取它的參考時,它就不能被存取了,也就成為垃圾物件了。通常物件的參考被賦予其他的值或是在頁面運行結束時,物件都會失去引用。
析構函數是在銷毀物件時,自動呼叫的,不能明確的呼叫。析構函數不能帶參數。
析構方法的宣告格式如下:
function deconstruct(){ //方法体,通常用来完成一些在对象销毁前的清理任务}
在下列幾種情況下可能會呼叫析構函式(但不一定):
PHP頁面載入完畢之後;
unset()類別;
#變數引用指向別的物件或值時;
PHP的記憶體回收機制和JAVA的很類似,對沒有任何引用的物件進行銷毀回收,採用引用計數器的技術。
範例:
<?php class test{ function destruct(){ echo "当对象销毁时会调用!!!"; } }$a = $b = $c = new test();$a = null;unset($b);echo "<hr />";?>
此例子,如下图,有三个变量引用$a,$b,$c指向test对象,test对象就有3个引用计数,当$a = null时,$a对test对象的引用丢失,计数-1,变为2,当$b被unset()时,$b对test对象的引用也丢失了,计数再-1,变为1,最后页面加载完毕,$c指向test对象的引用自动被释放,此时计数再-1,变为0,test对象已没有变量引用,就会被销毁,此时就会调用析构函数。
在PHP中析构方法并不是很常用,它属于类中可选的一部分,只有需要时才在类中声明。
<?phpclass Person{ var $name; var $sex; var $age; function construct($name, $sex, $age){ $this->name = $name; $this->sex = $sex; $this->age = $age; } function destruct(){ echo "再见" . $this->name . "<br />"; } } $person1 = new Person("张三三", "男", 23); $person1 = null; //第一个对象将失去引用 $person2 = new Person("李四四", "女", 17); $person3 = new Person("王五五", "男", 43); ?>
运行结果:
再见张三三 再见王五五 再见李四四
第一个对象在声明完成以后,它的引用就被赋予了空值,所以第一个对象最先失去的引用,不能再被访问了,人后自动调用第一个对象中的析构方法输出“再见张三三”。后面声明的两个对象都是在页面执行结束时失去的引用,也都自动调用了析构方法。但因为对象的引用都是放在栈内存中的,由于栈的后进先出特点,最后创建的对象会被最先释放,多以先自动调用第三个对象的析构方法,最后才调用第二个对象的析构方法。
以上是PHP物件導向-建構方法和析構方法的程式碼案例分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!