php面向对象,自动加载类,对象串行化,多态的应用
自动加载类:很多开发者写面向对象的应用程序时,对每个类的定义建立一个 PHP 源文件,一个很大的烦恼是不得不在每个脚本,每个类一个文件,开头写一个长长的包含文件的列表.
在软件开发的系统中,不可能把所有的类都写在一个PHP文件中,当在一个PHP文件中需要调用另一个文件中声明的类时,就需要通过include把这个文件引入,不过有的时候,在文件众多的项目中,要一一将所需类的文件都include进来,是一个很让人头疼的事,所以我们能不能在用到什么类的时候,再把这个类所在的php文件导入呢?这就是我们这里我们要讲的自动加载类.
在 PHP 5 中,可以定义一个 __autoload()函数,它会在试图使用尚未被定义的类时自动调用,通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类,__autoload()函数接收的一个参数,就是你想加载的类的类名,所以你做项目时,在组织定义类的文件名时,需要按照一定的规则,最好以类名为中心,也可以加上统一的前缀或后缀形成文件名,比如xxx_classname.php、classname_xxx.php以及就是classname.php等等.
本例尝试分别从 MyClass1.php 和 MyClass2.php 文件中加载 MyClass1 和 MyClass2 类,代码如下:
- function __autoload($classname)
- {
- require_once $classname . '.php';
- }
- //MyClass1类不存在自动调用__autoload()函数,传入参数”MyClass1”
- $obj = new MyClass1();
- //MyClass2类不存在自动调用__autoload()函数,传入参数”MyClass2”
- $obj2 = new MyClass2();
对象串行化
有时候需要把一个对象在网络上传输,为了方便传输,可以把整个对象转化为二进制串,等到达另一端时,再还原为原来的对象,这个过程称之为串行化, 就像我们现在想把一辆汽车通过轮船运到美国去,因为汽车的体积比较大,我们可以把汽车拆开成小的部件,然后我们把这些部件通过轮般运到美国去,到了美国再把这些部件组装回汽车。
有两种情况我们必须把对象串行化,第一种情况就是把一个对象在网络中传输的时候要将对象串行化,第二种情况就是把对象写入文件或是数据库的时候用到串行化。
串行化有两个过程,一个是串行化,就是把对象转化为二进制的字符串,我们使用serialize()函数来串行化一个对象,另一个是反串行化,就是把对象转化的二进制字符串再转化为对象, 我们使用unserialize()函数来反串行化一个对象.
PHP中serialize()函数的参数为对象名,返回值为一个字符串,Serialize()返回的字符串含义模糊,一般我们不会解析这个串来得到对象的信息,我们只要把返回来的这个字符串传到网络另一端或是保存到方件中即可.
PHP中unserialize()函数来反串行化对象,这个函数的参数即为serialize()函数的返回值,输出当然是重新组织好的对象,代码如下:
- class Person
- {
- //下面是人的成员属性
- var $name; //人的名子
- var $sex; //人的性别
- var $age; //人的年龄
- //定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值
- function __construct($name="", $sex="", $age="")
- {
- $this->name=$name;
- $this->sex=$sex;
- $this->age=$age;
- }
- //这个人可以说话的方法, 说出自己的属性
- function say()
- {
- echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."";//开源代码phpfensi.com
- }
- }
- $p1=new Person("张三", "男", 20);
- $p1_string=serialize($p1); //把一个对象串行化,返一个字符串
- echo $p1_string.""; //串行化的字符串我们通常不去解析
- $p2=unserialize($p1_string); //把一个串行化的字符串反串行化形成对象$p2
- $p2->say();
多态的应用
多态是除封装和继承之外的另一个面象对象的三大特性之一,我个人看来PHP中虽然可以实现多态,但和c++还有Java这些面向对象的语言相比,多态性并不是那么突出,因为PHP本身就是一种弱类型的语言,不存在父类对象转化为子类对象或者是子类对象转化为父类对象的问题,所以多态的应用并不是那么的明显;所谓多态性是指一段程序能够处理多种类型对象的能力,比如说在公司上班,每个月财务发放工资,同一个发工资的方法,在公司内不同的员工或是不同职位的员工,都是通过这个方法发放的,但是所发的工资都是不相同的。所以同一个发工资的方法就出现了多种形态。对于面向对象的程序来说,多态就是把子类对象赋值给父类引用,然后调用父类的方法,去执行子类覆盖父类的那个方法,但在PHP里是弱类型的,对象引用都是一样的不分父类引用,还是子类引用。
我们现在来看一个例子,首先还是要使用多态就要有父类对象和子类对象的关系。做一个形状的接口或是抽象类做为父类,里面有两个抽象方法,一个求周长的方法,另一个是求面积的方法;这接口的子类是多种不同的形状,每个形状又都有周长和面积,又因为父类是一个接口,所以子类里面就必须要实现父类的这两个周长和面积的抽象方法,这样做的目的是每种不同形状的子类都遵守父类接口的规范,都要有求周长和求面积的方法,代码如下:
- //定义了一个形状的接口,里面有两个抽象方法让子类去实现
- interface Shape
- {
- function area();
- function perimeter();
- }
- //定义了一个矩形子类实现了形状接口中的周长和面积
- class Rect implements Shape
- {
- private $width;
- private $height;
- function __construct($width, $height)
- {
- $this->width=$width;
- $this->height=$height;
- }
- function area()
- {
- return "矩形的面积是:".($this->width*$this->height);
- }
- function perimeter()
- {
- return "矩形的周长是:".(2*($this->width+$this->height));
- }
- }
- //定义了一个圆形子类实现了形状接口中的周长和面积
- class Circular implements Shape
- {
- private $radius;
- function __construct($radius)
- {
- $this->radius=$radius;
- }
- function area()
- {
- return "圆形的面积是:".(3.14*$this->radius*$this->radius);
- }
- function perimeter()
- {
- return "圆形的周长是:".(2*3.14*$this->radius);
- }
- }
- //把子类矩形对象赋给形状的一个引用
- $shape=new Rect(5, 10);
- echo $shape->area()."
- ";
- echo $shape->perimeter()."
- ";
- //开源代码phpfensi.com
- //把子类圆形对象赋给形状的一个引用
- $shape=new Circular(10);
- echo $shape->area()."
- ";
- echo $shape->perimeter()."
- ";
- //上例执行结果:
- //矩形的面积是:50
- //矩形的周长是:30
- //圆形的面积是:314
- //圆形的周长是:62.8