PHP面向对象
1. 内存结构;在逻辑上内存可以分成四段:栈空间段、堆空间段、数据段、代码段;
栈空间段空间小,CPU访问速度快,特点是后进先出。常用来存储一些占用长度固定、占用空间小的数据类型的内存段。如一些整形、浮点型等;
对空间段空间大小并不固定,可以动态扩张或者缩减,用于存放长度可变或者占用内存比较大的数据,如字符串、数组、对象;
数据段用来存放已经初始化的全局变量,即程序静态分配的变量;
代码段用来存放操作指令,也是可执行文件在内存中的镜像。
栈内存的空间是可以被程序直接存取的,而堆内存的空间不可以直接存取,而是通过将堆内存的地址存放到栈内存中,通过引用栈内存中的地址来存取堆内存。
2. PHP中的类通过class关键字声明,并通过new关键字实例化;
成员属性需要用var来声明,如果指定public、private、protected等,则不需要使用var;
成员函数通过function声明;
对象通过->来访问成员方法和属性;
3. PHP中$this 代表当前对象,self代表当前类,parent代表父类;
4. 构造方法:function __construct(){}定义一个构造方法,以供在实例化时调用;
析构方法:PHP中的析构由垃圾回收机制完成,function __destruct(){}定义的析构方法仅仅是在析构时会自动调用,而没有任何析构作用;
5. 封装性:private使属性或者方法在类定义之外不可调用,protected使属性或者方法在类定义或者子类定义之外不可调用,public使属性或者方法在任何地方调用;
6. __set()、__get()方法:PHP中的__set()、__get()有稍许不同,并不是对每一个属性单独调用,而是在__set()方法中完成所有可能传入的属性的set或者相关处理等过程,__set()方法定义时传入两个参数,分别为传入的属性和将要赋予的值,__get()方法类似,传入一个属性名称来获取;__set()、__get()方法在对象使用时和其他语言一样,可以到达直接访问或者赋值的效果;
7. __isset()、__unset()方法:这两个方法中的内容将作为对对象的属性进行isset()、unset()函数操作时调用的真正方法;
8. PHP不支持多重继承,百度了好几个PHP多重继承的实现,都是通过接口等操作来实现,并不是真正的多重继承,与此同时,不存在多重继承带来的继承顺序的问题;
9. 方法支持被重载,但是如果在类之前或者方法之前加上final关键字,那么这个类将不能被继承,这个方法不能被重载;
10. 通过static关键字声明类的静态成员或者静态方法,通过MyClass::$var,以及 MyClass::foo()的形式调用静态变量以及静态方法;
11. 单态设计模式:使得一个类只能实例化一个变量,避免例如实例化多个对象对数据库进行多次连接引起的消耗。具体实现是定义一个静态私有变量$obj,初始化为null,并且将构造方法私有化,在另外一个静态方法getInstance()中调用判断类的静态私有变量self::$obj(也是类的唯一对象)是否为null,如果是的话就调用构造方法,并赋值给self::$obj,如果不是,则直接返回self::$obj对象;该特殊类在实例化时,需要通过静态方法MyClass::getInstance()来实例化;
12. 类中的一些关键字:
const关键字可以在类中定义一个常量,并且是静态的;
instanceof关键字可以判断一个对象是否是一个类的实例: $obj isinstanceof MyClass,并得到布尔值;
clone关键字可以克隆一个对象,并且通过实现__clone()方法,可以对clone操作进行重定义;
13. 类中的通用方法:
__toString(),和python中的__str__()方法同,在echo中会调用;
__call(),和python中__call__()区别,而是类似于ruby中的幽灵方法(method_missing())。不是使对象可调用化,而是在对象调用方法不存在时,自动执行__call()方法中的内容,通过__call()方法的实现,可以在调用的方法不存在时做出一些反应,如将方法名转成小写调用等等;
书上使用了__call()方法实现了一个连贯操作的功能,这应该是目前在《细说PHP》见过最酷的黑科技了:
14. 类的自动加载,PHP中提供了一个__autoload()全局函数,当在php脚本中使用一个未知类时,会尝试在当前目录下include一个xxx.class.php或者之类的文件,其实现方式类似于:
function __autoload($classname){
include(strtolower($classname).”class.php");
}
15. 对象串行化,通过serialize()函数将一个对象串行化成二进制串,以便写入到文件或者数据库,或者传输到网络中;
通过unserialize()函数可以对读取的对象经行解串操作,恢复成对象之前的结构;
通过定义__sleep()方法可以自定义在串行化时的操作,通过返回一个数组自定义需要被串行化的属性,但是方法会被保留;
通过定义__wakeup()方法来定义在解串过程中,对串行化时可能丢失的属性进行定义;
16. 抽象类和接口:
通过abstract 关键字,定义一个抽象类: abstract class ,在抽象类中,可以定义抽象方法: abstract function();
继承自抽象类的类必须完成所有抽象方法,否则还是一个抽象类,并且必须以abstract声明;
通过interface 关键字,定义一个接口:interface MyClass;通过implements来实现接口的方法,同样的,必须实现接口中的全部方法,否则还是一个抽象类;
抽象类和接口不能实例化对象;
17. 多态:PHP中的多态通过实现一个相同的接口来实现。