单例模式
在实际项目中,有的类从头到尾只需要一个对象即可完成所有任务并希望针对这一个对象进行修改具体内容,这个类就是单例。
下面讲述具体的思路过程:
- 首先,理解一下普通类对象的构造过程:通过new语句和类名进而调用__construct方法来初始化对象。那么要防止通过new语句构造出多个对象的话就防止__construct函数被调用,即通过private私有化该函数
- 让我们来想想创建对象的另一种方式,即通过在方法调用new self来实现,这时候有会出现一个问题?这样在另一个方法内调用__construct不是一样吗?的确一样,不过我们可以通过参数来控制是否创建对象,这样就实现了单例
- 不过你有可能没发现__clone方法同样也能初始化对象,不过我们只需对其进行私有化就可以了
图示如下:第二步视图
通过结果我们发现通过getNew方法来实现的对象都是同一个对象,
方法getNew实现单例的思路如下:刚开时创建第一个对象时先判断一个静态示例$instance是否为空,为空就将调用__construct方法,不为空的话就返回该静态示例对象,这样就保证了该类只能创建一个对象
在实现完第三步的完整图示如下:
资源和对象的辨析
先来了解一下为什么要辨析资源和对象?在用面向对象语言来实现数据库操作时经常会发现常常先用到类对象和连接数据库,在初始化数据库操作和连接类时经常会搞错什么时候该用连接数据库返回的数据和该类产生的对象。那么我们来看看对象和类的区分吧?
简单来说:资源就是不存在于语言本身而在语言外部的数据,资源就类似于一个指针指向调用资源的地址来进而使用;对象就简单的就是类创建用来使用类的一个具体化变量。
图示如下:
结果为:
可见资源就是resuorce,对象就是object
抽象类、抽象方法
在大型项目中,有的类只需要创建一个对象进而产生了单例模式,同样有的类不需要产生对象,于是产生了抽象类和抽象方法
抽象类
在形式上看,抽象类与普通类相比无非是多了一个关键字:abstract
Abstract class 类名{…………}
该类一个明显的特征就是不能创建对象:
为了使用该类,我们就只能通过子类去继承用之,于是继承类又可叫做父类(规范性)
抽象方法
与抽象类相似,关键字:abstract
Abstract function f1($x1, $y, $m); //注意,抽象方法没有方法体有分号
该方法其实就是起声明作用,并必须在其子类中声明或重写,否则会报错:
抽象类抽象方法关系描述
- 如果一个方法定义为抽象方法,则其所在的类必须定义为抽象类
- 一个抽象类中可以没有抽象方法
- 子类继承自一个抽象类则子类必须实现父类的所有抽象方法,除非子类也继续作为抽象类
- 子类实现抽象父类的方法是访问控制修饰符的范围不能降低且方法的参数必须一致
PHP中的重载技术
通常面向对象语言的重载技术
在一个类中,常常需要方法名相同而参数不同的方法来处理不同情况,这种现象称为“重载”。
参数不同:数量个数不同、类型不同或顺序不同
比如:
Class A{
Int function f1(int x){}
Int function f1(int x, int y){}
Int function f1(string s, int m){}
}
但在PHP中,一个类不允许定义多个同名方法(语法错误),实际上PHP中的重载指的是:
属性重载:当使用一个不存在的属性,就会自动调用类中预先定义好的某个方法以处理数据
方法重载:当使用一个不存在的方法,就会自动调用类中预先定义好的某个方法以处理该行为
使用php中的重载机制既能处理语法错误,又能在一定程度上使用普通面向对象语言的重载
属性重载
属性重载会根据属性的使用情况来使用不同的处理函数
- 取值:$v1 = 对象->属性;
- 赋值:对象->属性 = XX值;
- 判断是否存在:isset(对象->属性);
- 销毁:unset(对象->属性);
其对应处理方法机制为:
- __get()方法
- __set()方法
- __isset()方法
- __unset()方法
不过我们都需要预先定义好这些方法:
取值:
赋值:
__get和__set函数配合完成
判断存在和销毁机制如下:
方法重载
当使用一个对象调用一个不存在的普通方法的时候会自动调用预先定义好的“__call”方法,该方法必须带2个参数
当使用一个对象(类)调用一个不存在的静态方法的时候,会自动去调用预先定义好的"__callStatic"方法。
必须带2个参数
上面所学的几个方法都被称为“魔术方法”
__get、__set()、__isset()、unset()、__call()、callstatic;
接口inteface
类:有属性,有方法,有类常量
抽象类:有属性、方法、类常量、抽象方法(方法头)
接口:接口常量、抽象方法(只有方法头)
注意:接口的一大特征就是接口能实现“多继承”(多实现)
一个类只能只能继承一个父类,但可以实现多个“上级接口”,语法形式:
Class 类A extends 类B implements 接口1,接口2,…{}
一个接口同样可以继承另一个接口(也是单继承):
Interface 接口1 extends 接口2 {接口定义}