一、基本概述
核心思想
万物皆对象
类由属性和方法组成
类是对象的集合,对象是类的实例化
访问方式
在类的内部:
普通属性方法:$this->普通属性名/方法名();
静态属性方法或常量:self::静态属性名/方法名/常量名;
在类的外部:
普通属性方法:$保存对象的变量->普通属性名/方法名();
静态属性方法或常量:类名::属性名/方法名/常量名;
类常量
定义方式:const 常量名 = 值;
注意:
1. 类常量的值必须是一个定值,不能修改,也不能删除;
2. 类常量没有权限,可以被所有对象共享
二、主要特性
封装
定义:把一些常用的功能集合到一起形成一个类
作用:提高代码的复用性
基本原则:
1. 属性尽量定义为私有
2. 方法尽量定义为公开的
3. 需要被子类继承的属性和方法尽量定义为受保护的
继承 ( extends )
定义:子类可以继承父类的属性和方法
作用:实现功能的升级和扩展
流程:现在本类查找,找到就用自己的,如果找不到就去父类或祖先类中查找
关键字:parent 在子类中代表父类或祖先类的类名 (parent::类常量 | 静态属性 | 静态方法 | 成员方法)
特点:
1. PHP 中只能是单继承
2. 子类的修饰符范围不能比父类小
3. 子类可以继承父类的所有属性,但私有属性只能看不能用
访问限定修饰符:
public: 公开的,在类的内部、外部和继承链中都能直接访问
protected: 受保护的,只能在类的内部和继承链中直接访问
private: 私有的,只能在本来的内部被直接访问
重写:
定义:在子类中出现跟父类同名的成员时,子类中的内容会覆盖父类
注意:
1. 尽量避免重写
2. 当重写不可避免时(如构造方法),在子类中显示的调用父类的构造方法(parent::__constract)
3. 父类方法权限为private,子类无法继承,也无法重写
多态
定义:一种方法可以有多重实现方式,主要表现为方法重载或方法重写
三、单例模式
定义:一个类只能产生一个对象
实现方式( 三私一公 ):
私有的构造方法:阻止用new关键字产生多个对象
公开一个静态的方法:用来在类的外部产生一个对象
私有一个静态属性:用来保存静态方法在类的内部new的对象
私有克隆方法:阻止从类的外部clone多个对象
class Instance
{
// 2. 私有的静态属性
private static $instance;
// 1. 私有的构造方法
private function __construct(){}
// 3. 私有的克隆方法
private function __clone(){}
// 4. 公开的静态方法
public static function getInstance()
{
// 判断是否是第一次调用
if (!self::$instance instanceof self) {
self::$instance = new self;
}
return self::$instance;
}
}
四、构造方法和析构方法
构造方法
定义:当使用new关键字创建对象完成时,第1个自动调用的方法,就是构造方法
void __construct ([ mixed $args [, $... ]] )
作用:对象初始化。例如:给对象属性赋值、数据库对象初始化(连接、选择数据库)
析构方法
定义:对象销毁前自动调用的方法,就是析构方法
注意:析构方法不带任何参数
void __destruct ()
作用:垃圾回收工作,例如:断开到MySQL的连接
调用时机:
程序执行完毕时
给对象赋空值时
手动销毁unset() 时
五、值传递和引用传递
值传递
定义:将一个变量的“数据”或“值”,复制一份,传递给另一个变量(相当于复制粘贴)
默认情况下,PHP值传递的数据类型有:字符串型、整型、浮点型、布尔型、数组型、NULL
引用传递
定义:将一个变量的“数据地址”,复制一份,传递给另一个变量(相当于快捷方式)
默认情况下,PHP引用传递的数据类型有:对象和资源
六、重载
PHP 的定义:当访问一个不能访问的成员时,触发魔术方法
特点: 所有的重载方法都必须被声明为 public
自定义(非静态)属性的重载
写操作: __set()
public void __set ( string $name , mixed $value )
读操作:__get()
public mixed __get ( string $name )
调用 isset() 或 empty() 时,__isset() 会被调用
public bool __isset ( string $name )
调用unset() 时,__unset() 会被调用
public void __unset ( string $name )
自定义方法的重载
访问不可访问的普通方法时,__call() 会被调用
public mixed __call ( string $name , array $arguments )
访问不可访问的静态方法时,__callStatic() 会被调用
public static mixed __callStatic ( string $name , array $arguments )
七、最终类和最终方法
最终类
定义:final关键字修饰的类
特点:该类只能实例化,不能被继承
最终方法
定义:final关键字修饰的方法
特点:该方法可以被继承,但不能重写
八、抽象类和抽象方法
抽象类
定义:abstract关键字修饰的类
特点:
该类不能直接实例化,必须先继承后再实例化
如果一类中有一个抽象方法,该类必须是抽象类
抽象方法
定义:abstract关键字修饰的方法
特点:
抽象方法没有方法体,必须在子类重写后,再定义方法体
所有的抽象方法都必须重写,少一个都不行
抽象方法权限不能是private,因为要先继承再重写
抽象方法只能是成员方法,而不能是静态方法
九、接口
interface 关键字定义接口 ,且接口中方法默认是抽象的
implements 关键字用来实现接口,类可以实现(implements)多个接口
接口中方法权限必须是public
接口中也可以定义常量,但常量不能重写
十、自动加载
常规加载:__autoload()
作用:加载类定义文件(定义类),加载文件只能通过include
前提:加载类名与文件名保持一致,并且命名规则一致
自动加载的原理:
当使用一个类且类不存在的时候,php会自动调用__autoload,将找不到的类名赋值给$className
在__autoload函数中,通过代码,加载一定规则的文件
类的自定义加载 : spl_autoload_register()
定义一个函数
将函数注册到自动加载
class Load
{
public static function f1($className)
{
// 构建文件名
$filename = "./{$className}.class.php";
// 判断文件是否存在
if (file_exists($filename)) {
include $filename;
}
}
}
// 将静态方法告诉PHP
spl_autoload_register("Load::f1");
十一、工厂设计模式
作用:根据传递不同的类名参数,返回不同类的对象
// 定义工厂类
// 作用:根据类名,产生对象
class Factory
{
/**
* 根据className产生对象
* @param [string] $className [需要产生的类名]
* @return [type] [description]
*/
public static function produce($className)
{
// echo $className;
include "./{$className}.class.php";
return new $className;
}
}
$stu = Factory::produce('Student');
var_dump($stu);
十二、命名空间
作用:在同一个脚本文件中能使用同名的类和函数
语法:namespace 空间名
注意:第一个命名空间定义之前不能有任何输出
文件包含不影响当前空间
受命名空间影响的元素:函数 、类 、const 常量
空间元素的访问
非限定访问方式:
(直接使用) 当调用元素时,就近找命名空间。名称中不包含命名空间分隔符,例如 Foo
完全限定访问方式:
在一个空间访问另一个空间的元素。以命名空间分隔符开始,例如 \Foo\Bar, namespace\Foo 也是一个完全限定名称
限定访问方式:
类似于相对路径,跟当前的空间去拼接形成一个路径。例如 Foo\Bar
根空间
根空间就是 ‘ \ ’
当没有定义命名空间时,默认就在根空间下
当定义了命名空间时,就是根空间下的对应空间,比如namespace A;
引入空间类元素
语法:use 空间名
注意:use 关键字只是相当于给空间名取别名,并不会起到 include 引入文件的作用
十三、对象的遍历
借助PHP中的一个预定义接口:Iterator
class A implements Iterator{
public $var1='r1';
public $var2=['name'=>'zhangsan', 'age'=>12, 'weight'=>100];
// 重置数组指针
public function rewind(){
reset($this->var2);
}
// 获得数组元素的值
public function current(){
return current($this->var2);
}
// 获得数组元素的键
public function key(){
return key($this->var2);
}
// 将数组元素的指针向下移动一位
public function next(){
next($this->var2);
}
// 判断当前指针是否有效
public function valid(){
if( key($this->var2)!==NULL ){
return true;
}else{
return false;
}
}
}
$a1 = new A;
var_dump( $a1 ); echo '<hr/><hr/>';
foreach( $a1 as $k=>$v ){
echo 'k:' . $k . '<br/>';
echo 'v:' . $v . '<hr/>';
}
十四、序列化和反序列化
序列化
通过serialize() 函数将某个对象转换成一个既包含对象数据,也包含对象数据的数据类型的字符串
当序列化对象时,serialize()函数会检查类中是否存在一个魔术方法 __sleep()
__sleep() 功能:表示能够筛选哪个属性应该被序列化,哪些属性不被序列化
public array __sleep ( void )
反序列化
可以通过unserialize() 函数来将序列化后的对象字符串还原成原始对象
当对象反序列化时,unserialize()函数会检查类中是否存在一个__wakeup() 方法
__wakeup() 功能:能够重新初始化回部分属性的数据
void __wakeup ( void )
十五、静态延时绑定
关键字:static
功能:在继承范围内引用静态调用的类
使用static访问子类的静态成员,这个static表示哪个类调用,就代表那个类
self永远代表当前类,static代表最终执行(调用)的类
十六、反射机制
作用:了解了的内部结构
get_declared_classes 获得当前程序脚本中所定义出的所有类的类名。
get_class_methods 获得类中定义的方法信息。
分类
类的反射
ReflectionClass::export 反射指定的类的信息
getFileName 反射类所在的文件名
implementsInterface 判断某个类是否实现了某个接口
类常量的反射
getConstants方法 获得所有相关常量的信息
类属性的反射
getProperties方法 获得类中所有属性的信息
类方法的反射
getMethods方法 获得类中所有方法的信息
类方法的参数反射
ReflectionMethod::export