### 类与对象
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 类名;
~~~
访问对象属性:
~~~
对象名->‘属性名’;
//对象运算符:->
~~~
对象的传递方式
![](https://box.kancloud.cn/110562d750badb223dc10d0b145295b0_942x402.png)
按引用传递
![](https://box.kancloud.cn/9dae3803cbe2fd769ba090d7d15fa3b6_869x313.png)
### 成员函数
~~~
访问修饰符 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对象的时候
* 先创建的对象后被销毁,栈的先进后出规则。
![](https://box.kancloud.cn/a9a44c84c01e4a4f6ff6787cfe10e389_231x234.png)
~~~
function __destruct(){
echo $this->name;.'被析构函数销毁';
}
~~~
![](https://box.kancloud.cn/af741aacbf32967bd336d467786a7501_768x386.png)
#### 析构函数实践:
希望在程序没有结束前,就销毁某个对象实例。及时释放重量级对象 $person=null;
对象销毁,但是数据库连接还能用,在析构函数中,手动销毁数据库连接。
程序退出前,php也将启用垃圾回收机制,销毁对象。
### this用法
this只能在类的方法里面使用。
![](https://box.kancloud.cn/e496f282dee62aa2fa29d1cbc3855a72_674x253.png)
### 垃圾回收机制
### 访问修饰符
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();
~~~
![](https://box.kancloud.cn/78bbdbbcf77d6840779e8a4ea89e3a43_509x332.png)
### spl_autoload_register('function');自动加载函数的注册
![](https://box.kancloud.cn/e6d44a3413744951143ccadf020b2579_563x327.png)
### 静态属性和静态方法
* 静态属性是所有对象共享的变量,如果有修改,也是所有对象的都被修改。
* 无需实例化可直接访问
* * ::范围解析符
* * public static 变量名
* * 方法中访问:self::变量名,类的外部访问,类名::变量名
* 静态变量可以在定义的时候初始化
~~~
public static $num;
function total(){
self::$num;
}
~~~
![](https://box.kancloud.cn/abf959e30c6ee4e4d3c7a7db88579fca_748x299.png)
### self和this的区别
* self是类范畴,指向类
* $this是对象实例(指向对象实例)
### 静态方法:
* 访问修饰符 static function 函数名(){}
* 调用:self::函数名(); 类的内部,$this->也可以调用,self更规范
* 静态方法中不能调用非静态属性
* 普通成员方法可以访问静态属性
* 如果静态方法是proteced,类的外部不能使用
![](https://box.kancloud.cn/db40092071cfbabb0562f65db0d26eb7_422x186.png)
**没有对象实例的时候调用:**
类名::函数名
**实例化后可以:**
对象名->函数名();
1. 一般用静态方法操作静态变量
2. 可以在没有实例化的情况下直接调用该方法,(实现单例模式时)
**小结:**
* 所有对象共享的数据可以定义静态属性
* 静态属性是与类相关的
### 单例模式
![](https://box.kancloud.cn/59ec6c121b926d157fd4ef73c681cd48_425x307.png)
![](https://box.kancloud.cn/f4e70ef8a4de0851a15ce12cac9d375b_583x389.png)
![](https://box.kancloud.cn/cbd36f528f8d8f5635009c19dcea2ab3_592x438.png)
### 抽象
抽象是一种研究问题的思路和方法,将一类事物的共同特点提取出来,做成事物的属性和方法。如:银行卡
面向对象3大特征:封装,继承,多态