### 類與對象
1. 類與對象
2. 構造方法、析構方法
3. 成員方法
4. this
5. 垃圾回收器
6. 類的魔術方法
7. 類的自動加載
一、基本用法入門
~~~
//類
class Cat{
//貓的三個屬性
public $name;
public $age;
public $color;
}
//創建對象實例
$cat1=new Cat();
$cat1->name='小貓名字';
$cat1->age='5歲';
$cat1->color='黑色';
echo $cat1->name.$cat1->age.$cat1->color;
~~~
### 規范說明
類名:大寫字母開頭,駝峰發,動詞放前面,名詞放后面
~~~
//使用默認構造函數,效果一樣
$對象名=new 類名();
$對象名=new 類名;
~~~
訪問對象屬性:
~~~
對象名->‘屬性名’;
//對象運算符:->
~~~
對象的傳遞方式

按引用傳遞

### 成員函數
~~~
訪問修飾符 function jisuan(){}
~~~
使用:
$person1->speak();
### 構造函數
創建類的時候,就指定成員屬性,完成初始化任務。
無需return即可使用
~~~
class Cat{
//成員屬性
public $name;
public function __construct(形參){
//函數體
}
}
~~~
this是變化的,指向類的當前實例具體對象,就表示這個對象實例
構造函數和成員方法里面要使用類變量,都得通過類的this指向,不然就是函數里面的局部變量
* 構造函數沒有返回值
* 實例化對象的時候,自動調用
* php4中,構造函數和類名一樣,php5種使用的是__construct
* 如果沒有寫構造函數,系統默認會生成一個無參數的構造函數
* 一個類只有一個構造函數
*構造函數的參數,一定要在實例化的時候傳入參數
~~~
public function __construct(){}
~~~
~~~
//類
class Person{
//成員屬性
public $name;
public $age;
//構造函數
public function __construct($myname,$myage){
$this->name=$myname;
$this->age=$myage;
}
}
$person1=new Person('豬八戒',200);
echo $person1->name;
echo $person1->age;
~~~
### 析構函數
釋放對象分配的相關資源。如:釋放數據庫連接,釋放文件的打開
某個對象的所有引用被刪除或銷毀的時候使用。
什么時候觸發析構函數:
* 對象運行結束前,也會調用析構函數
* unset()或者Null對象的時候
* 先創建的對象后被銷毀,棧的先進后出規則。

~~~
function __destruct(){
echo $this->name;.'被析構函數銷毀';
}
~~~

#### 析構函數實踐:
希望在程序沒有結束前,就銷毀某個對象實例。及時釋放重量級對象 $person=null;
對象銷毀,但是數據庫連接還能用,在析構函數中,手動銷毀數據庫連接。
程序退出前,php也將啟用垃圾回收機制,銷毀對象。
### this用法
this只能在類的方法里面使用。

### 垃圾回收機制
### 訪問修飾符
public 類的外部和內部任意訪問
protected 子類或父類訪問,不能在類的外部訪問,如果要訪問,需要寫一個公開的方法來訪問
private 在自身的類里面訪問。在類的外部使用公開的方法來訪問。
~~~
class Person{
//成員屬性
public $name;
protected $age;
//構造函數
public function __construct($myname,$myage){
$this->name=$myname;
$this->age=$myage;
}
public function getage(){
return $this->age;
}
}
$person1=new Person('豬八戒',200);
echo $person1->name;
echo $person1->getage();
~~~
### 魔術方法
~~~
__construnct
__destruct
__call
__callStatic
__get
__set
__isset
__unset
__sleep
__wakeup
__toString
__invoke
__set_state
__clone
~~~
魔術方法在滿足某種條件下,自動被系統調用
#### __get
讀取不可訪問的屬性的值。如:proteced /private/不存在
#### __set
設置不可訪問的屬性的值
~~~
class Person{
//成員屬性
public $name;
protected $age;
//構造函數
public function __construct($myname,$myage){
$this->name=$myname;
$this->age=$myage;
}
function __get($pro_name){
if(isset($this->$pro_name)){
return $this->$pro_name;
}else{
echo "屬性不存在";
}
}
function __set($pro_name,$val){
if(isset($this->$pro_name)){
$this->$pro_name=$val;
}
}
}
$person1=new Person('豬八戒',200);
echo $person1->name;
echo "<br>";
echo $person1->age;
$person1->age='1000';
echo "<br>";
echo $person1->age;
~~~
### isset,unset
對不可訪問的屬性調用isset()或empty()的時候,__isset()會被調用
對不可訪問的屬性調用unset的時候,__unset會被調用
~~~
class Person{
//成員屬性
public $name;
protected $age;
//構造函數
public function __construct($myname,$myage){
$this->name=$myname;
$this->age=$myage;
}
function __isset($pro_name){
return isset($this->$pro_name);
}
function __unset($pro_name){
if(isset($this->$pro_name)){
unset($this->$pro_name);
}
}
}
$person1=new Person('豬八戒',200);
if(isset($person1->age)){
echo 'age存在';
}else{
echo 'age不存在';
}
echo "<pre>";
var_dump($person1);
unset($person1->age);
var_dump($person1);
~~~
### __toString()
把類當做字符串輸出
~~~
class Person{
//成員屬性
public $name;
protected $age;
//構造函數
public function __construct($myname,$myage){
$this->name=$myname;
$this->age=$myage;
}
function __toString(){
return "tostring返回信息:".$this->name.'__'.$this->age;
}
}
$person1=new Person('豬八戒',200);
echo $person1;
~~~
### 克隆 clone
克隆魔術函數主要是在單例模型中,防止別人克隆
~~~
private __clone(){}
//克隆不成功
$person2=clone $person1;
~~~
### __call
調用一個不可訪問的方法時候,系統自動調用__call
~~~
class Person{
//成員屬性
public $name;
protected $age;
//構造函數
public function __construct($myname,$myage){
$this->name=$myname;
$this->age=$myage;
}
public function getsum($n1,$n2){
return $n1+$n2;
}
function __call($method,$args){
return $this->$args[0]($args[1],$args[2]);
}
}
$person1=new Person('豬八戒',200);
$res=$person1->showinfo('getsum',3,5);
echo $res;
~~~
### 類的自動加載 __autoload
使用一個沒有定義的類,會自動加載autoload函數
~~~
<?php
function __autoload($class_name){
require './$class_name'.'.class.php';
}
$cat=new Cat();
~~~

### spl_autoload_register('function');自動加載函數的注冊

### 靜態屬性和靜態方法
* 靜態屬性是所有對象共享的變量,如果有修改,也是所有對象的都被修改。
* 無需實例化可直接訪問
* * ::范圍解析符
* * public static 變量名
* * 方法中訪問:self::變量名,類的外部訪問,類名::變量名
* 靜態變量可以在定義的時候初始化
~~~
public static $num;
function total(){
self::$num;
}
~~~

### self和this的區別
* self是類范疇,指向類
* $this是對象實例(指向對象實例)
### 靜態方法:
* 訪問修飾符 static function 函數名(){}
* 調用:self::函數名(); 類的內部,$this->也可以調用,self更規范
* 靜態方法中不能調用非靜態屬性
* 普通成員方法可以訪問靜態屬性
* 如果靜態方法是proteced,類的外部不能使用

**沒有對象實例的時候調用:**
類名::函數名
**實例化后可以:**
對象名->函數名();
1. 一般用靜態方法操作靜態變量
2. 可以在沒有實例化的情況下直接調用該方法,(實現單例模式時)
**小結:**
* 所有對象共享的數據可以定義靜態屬性
* 靜態屬性是與類相關的
### 單例模式



### 抽象
抽象是一種研究問題的思路和方法,將一類事物的共同特點提取出來,做成事物的屬性和方法。如:銀行卡
面向對象3大特征:封裝,繼承,多態