類別與物件
類別的構成
物件的創建
PHP垃圾回收機制
$this解說
PHP是物件導向的程式語言,那麼什麼是物件導向呢?我們為什麼要面向對象呢?在我們的生活中有很多事物都是對象,例如一個杯子,一個盒子等,它們都有自己獨特的特徵,它們都是對象。而我們在開發中的開發也是物件導向程式設計的。對像是人們要進行研究的任何事物,從最簡單的整數到複雜的飛機等均可看作對象。我們使用物件導向程式設計可以讓我們看問題能夠看得全面,同時也有利於與資料的管理與維護,在PHP中物件導向可以分文兩類,一類是模子,創造物件使用,一類是物件,使用模子創建的起來的,那麼它們兩個有什麼關係呢?
類別與物件:具有相同特性(資料元素)和行為(功能)的物件的抽象就是類別。因此,對象的抽像是類,類的具體化就是對象,也可以說類的實例是對象,類其實就是一種資料型態。
也就是說把物件的功能和特徵抽取出來,組成一個類,就好比把一個杯子的模型抽取出來,而我們可以根據這個模型(也就是類)去創建各種杯子(也就是對象)。
那麼類別是怎麼定義的呢?物件又是怎麼創建的?
<?php class Cat{ //定义一个猫类 public $name; //猫的名字 public $age;//猫的名字 public $color;//猫的颜色 //猫的构造方法 public function __construct(){ } public function sleep(){ echo '猫睡觉'; } public function eat(){ echo '猫吃饭'; } }
上面的就是一個類別的基本結構,下面我們詳細的講解每個部分的意義。
class 是一個關鍵字,不能修改,表示這是一個類別。
Cat是類別名, 類別名稱寫法是大寫字母開頭,駝峰命名。
屬性: 成員屬性是類別的一個組成部分,通常是基本資料型別(整數,字串等) ,也可是複合型別(物件、陣列) , 資源型別。例如我們前面定義貓類別的public $age 就是成員屬性。
可以說每個類別都有屬性,類別的屬性是一類的特徵,比如說貓可以有名字,年齡,顏色等,這些貓類別共有的特徵。在類別中這種特徵我們稱為屬性,當然也可以不定義屬性。這個看自己的需求。
屬性前面的public是一個權限修飾符,在後面會有講解。
在上面的程式碼中可以看到在類別中還有幾個函數,它們和前面的函數是一樣的,不過是前面多了一個權限控制符。也可以叫做成員方法,這些成員方法就是類別中的行為動作,例如上面的貓類,有睡覺這個行為,也有吃飯這個行為,當然你可以自己寫它有什麼行為。
成員方法的語法:
访问修饰符 function 函数名(形式参数){ //函数体; //return 返回值; }
存取修飾符, 有三種(public, protected, privte), 預設為public, 後面我們會詳解
其它部就跟我們學的函數一樣了,包含呼叫機制
參數清單可以有多個,可以是任意型別
#對於方法的回傳值,這個可以看具體需求。
成員方法是定義在類別中的,如果定義在類別外就不是這個類別的行為了。
上面的貓類別中有一個方法,方法名稱是—__construct(),這是個建構函數,那麼什麼是構造函數?建構函數就是在創建物件的時候,進行初始化資料的方法,例如我們想在創建貓類別物件的時候,直接把貓的名字、年齡和顏色給它,就可以使用到建構子。
public function __construct($name,$age,$color){ $this-> name = $name; $this-> age = $age; $this-> color = $color; }
建構子的語法是:
public function __construct(形式参数){ //函数体 }
對於建構子的方法名稱__construct(),這個是魔術方法,後面有介紹,其實建構子還有一種寫法,建構函數的方法名稱是類別的名稱:
public function Cat($name,$age,$color){ }
上面的建構方法定義方式也是正確的,但是推薦使用魔術方法的那一種(__construct()),以為這樣當我們的類別名稱發生改變的時候,不用修改。
注意PHP中類別的名字不區分大小寫,但我們還是要用大小寫來寫。同時建構函數是沒有回傳值的。
建構子需要注意的是:
在一個類別中,只能有一個建構子, 這個是強制要求
建構子是系統自動呼叫的,我們不用自己調。
如果我們沒有定義一個建構函數,系統會使用一個預設的建構函數,形式如下:public function
__construct(){ },所以不管我們有沒有定義建構函數,它都是有建構子的。
上面的三种情况就是类中大致的内容,在后续我们还会降类中的其他情况。
在上面创建对象的类已经有了,那么怎么创建对象呢?
$cat = new Cat();
创建对象的语法是:
$对象名 = new 类名(参数1,参数2);
类名后面的括号里的参数是传递给类的构造函数的,如果构造函数没有参数,可以不写。
对象的命名规范和普通变量一样,使用驼峰法或者下划线法均可
new也是一个关键字,不能修改,表示新创建对象
我们创建对象的目的就是需要操作对象,而操作对象,就是操作对象里面的属性和方法。
在上面的类下面写如下代码:
//创建对象,传递三个参数到构造函数。 $cat = new Cat('小花',12,'black'); //通过对象来访问对象的属性 echo $cat -> name; echo '<br>'; echo $cat -> age; echo '<br>'; echo $cat -> color; echo '<br>'; $cat-> sleep(); $cat-> eat(); .....结果...... 小花 12 black 猫睡觉 猫吃饭
上面的对象通过->访问属性和方法。注意属性的前面没有$符号。
$对象名->属性名= 值; echo $对象名->属性名; '-> ' 称为对象运算符.
上面的就是对象的创建和最基本的应用
当我们把对象的值赋给另外一个变量是,是值传递还是引用传递?
//创建一个对象 $cat = new Cat('小花',12,'black'); $cat1 = $cat; // 把$cat这个对象赋给$cat1; $cat1 -> name = '小白';//利用$cat1这个对象修改对象的名字。 echo $cat1 -> name; //输出$cat1对象的名字。 echo '<br>'; echo $cat -> name; //输出$cat对象的名字。 .....结果...... 小白 小白
看到这里可能有点蒙,不是值传递吗?怎么修改一个对象的属性,另外一也变了?,
上面的代码当中 $cat1=$cat也是值传递,但是这个值是对象的引用(可以理解对象标识符),即每个包含对象的变量都持有对象的引(reference),而不是整个对象的拷贝。
在上面的图中可以看到,当$cat赋值给$cat1时,也就是对象标识符(#1)复制了一份,赋给$cat1,其实他们还是指向同一块数据区,所以只要其中一个修改了值,另外一个也会变。
我们使用完对象后,已经确定在以后不会使用这个对象了,这个时候我们可以手动的销毁对象,那么我们怎么让对象销毁呢?
当没有任何变量指向对象时,会销毁,因此我们可以把对象引用置为null
使用unset()函数来销毁对象。
//创建一个对象 $cat = new Cat('小花',12,'black'); $cat -> sleep(); unset($cat); $cat -> sleep(); .....结果..... 猫睡觉 Notice: Undefined variable: cat in D:\mywamp\Apache24\htdocs\zendstudio\yunsuanfu\object.php on line 27 Fatal error: Call to a member function sleep() on null in D:\mywamp\Apache24\htdocs\zendstudio\yunsuanfu\object.php on line 27
其实在一个文件运行完的时候,PHP会启动垃圾回收机制,自动的进行垃圾回收。这时候在里面创建的对象就自动销毁了,那么什么是PHP的垃圾回收机制?
垃圾回收,顾名思义,回收垃圾的,在程序中启动垃圾回收机制的时机:
在php中,当一个对象没有任何引用指向它的时候,就会成为一个垃圾对象,php将启动垃圾回收器将对象销毁。
当程序退出前,php也将启用垃圾回收器,销毁对象。
那么什么是垃圾回收机制?
垃圾回收机制是php5之后才有的,php5.3之前使用的垃圾回收机制是单纯的“引用计数”,也就是每个内存对象都分配一个计数器,当内存对象被变量引用时,计数器+1;当变量引用撤掉后,计数器-1;当计数器=0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成。但是PHP5.3开始,使用了新的垃圾回收机制,在引用计数基础上,实现了一种复杂的算法,来检测内存对象中引用环的存在(对象的相互引用),以避免内存泄漏。
在上面写类的构造函数的时候,可以看到在函数中使用到了$this,那么在面向对象中$this是什么?
$this是在类中使用的访问自身的一种机制。系统会给每个对象分配$this,代表当前对象。通俗的说就是在当前环境下,谁调用,$this就代表哪个对象。
<?php class Cat{ //定义一个猫类 public $name; //猫的名字 public $age;//猫的名字 public $color;//猫的颜色 //猫的定义方法 public function Cat($name,$age,$color){ $this-> name = $name; $this-> age = $age; $this-> color = $color; } public function sleep(){ echo '猫睡觉<br>'; } public function eat(){ echo '猫吃饭<br>'; } //输出猫的信息 public function info(){ echo '猫的名字是' . $this -> name . ' 年龄是' . $this-> age . ' 颜色是' . $this-> color; } } //创建一个对象 $cat = new Cat('小花',12,'black'); $cat -> info(); echo '<br>'; //创建另一个对象,传进不同的属性 $cat1 = new Cat('小白',6,'white'); $cat1 -> info(); .....结果..... 猫的名字是小花 年龄是12 颜色是black 猫的名字是小白 年龄是6 颜色是white
在上面的类中的info()函数中使用$this,不同的对象输出不同的结果,因为在不同的环境下,谁调用,$this就代表哪个对象。
在上面我们提到过,对象的销毁,其实在类中有一个方法,就是在对象销毁的时候由系统自动执行的。我们称之为析构函数。
public function __destruct(){ echo $this->name . '被销毁了<br>'; }
在PHP5中引入了析构函数的概念,析构函数会在某个对象的所有引用被删除(没有变量指向对象,要被销毁了),对象销毁前执行。
析构函数的主要作用是去释放对象分配的相关资源,比如数据库连接或打开的文件等。
它的语法是:
function __destruct(){ //函数体[释放资源,比如数据库连接,或者打开文件等等] }
析构函数也是系统自动调用的,我们不用自己调。但是当我们没有写析构函数的时候,系统不会执行析构函数。
<?php class Cat{ //定义一个猫类 public $name; //猫的名字 public $age;//猫的名字 public $color;//猫的颜色 //猫的定义方法 public function Cat($name,$age,$color){ $this-> name = $name; $this-> age = $age; $this-> color = $color; } public function sleep(){ echo '猫睡觉<br>'; } public function eat(){ echo '猫吃饭<br>'; } //输出猫的信息 public function info(){ echo '猫的名字是' . $this -> name . ' 年龄是' . $this-> age . ' 颜色是' . $this-> color; } public function __destruct(){ echo $this->name . '被销毁了<br>'; } } //创建一个对象 $cat = new Cat('小花',12,'black'); echo $cat -> name; //输出对象的名字 echo '<br>'; unset($cat); //销毁对象,系统自动调用析构函数。 .....结果...... 小花 小花被销毁了
当我们销毁对象$cat时,析构函数自动执行。
析構函數是在物件銷毀前自動執行的,它沒有回傳值。切一個類別中只能有一個析構函數。
析構函數是銷毀物件創建的資源,不是銷毀物件本身,物件本身是由垃圾回收機制銷毀的。
當我們一個文件中創建了多個對象,在文件執行完畢,銷毀對象的時候,是先創建的對象後銷毀,後創建的對象,先銷毀,這個原理和棧的原理很想,先進後出,後進先出。
透過上面對類別和物件的講解,我們可以知道類別和物件的區別和聯繫。類是抽象的,代表一類事物,如貓類。對象時具體的,代表一個具體事物。類別是物件的模板,物件是類別的一個實例。同時類別的基本構成要掌握。
以上就是PHP基礎教學九之類與物件的內容,更多相關內容請關注PHP中文網(www.php.cn)!