面向对象(四)

前言:这个章节主要分享一些高级的PHP面向对象的知识

(一) 两种常见的设计模式(单例和工厂模式)

  引言:在PHP中,存在两种常见的设计模式,一个是单例模式,另一个是工厂模式,这两中设计模式,并不是固定的PHP语法,而是广大的开发工作者在长期的开发工作中总结出来的开发经验。

  1.单例模式

<?php
//单例模式实现的目标效果是: 无论我们实例化多少次,都只能得到唯一的一个对象(空间)。
class A{
    private static $_obj;//定义了一个  静态的  私有的  属性

    //将构造方法私有化,使得无法在类的外部使用new关键字实例化这个类的对象
    private function __construct(){ 

    }

    private function __clone(){ 

    }

    //定义一个共有的  静态的  方法single
    public static function single(){ 

        //判断$_obj静态私有属性是否保存了一个本类的对象
        if( empty(self::$_obj) ){//如果$_obj为空,则表示之前没有创建过本类的对象
            self::$_obj = new self;
        }
        return self::$_obj;
    }
}

  2.工厂模式

<?php

class Factory{

    public static function produce($className){ 

        if( $className==‘A‘ ){

            include ‘./A.class.php‘;

        }elseif( $className==‘B‘ ){

            include ‘./B.class.php‘;
        }

        $obj = new $className;
        return $obj;
    }
}

$a1 = Factory::produce(‘A‘);
var_dump( $a1 ); echo ‘<hr/>‘;
$b1 = Factory::produce(‘B‘);
var_dump( $b1 ); 

  (二) 对象遍历

   引言:对象和数组本质上同属于复合数据类型,我们可以在程序中可以对数组进行遍历。

  1.默认的对象遍历

<?php

class A{

    public $name=‘zhangsan‘;
    public $age=12;
    public $height=1.8;
}

$a1 = new A;
var_dump( $a1 ); echo ‘<hr/>‘;echo ‘<hr/>‘;

//实现使用foreach对对象进行遍历
foreach( $a1 as $k=>$v ){ 

    echo ‘$k:‘;
    var_dump( $k ); echo ‘<br/>‘;
    echo ‘$v:‘;
    var_dump( $v ); echo ‘<hr/>‘;
}//小结:默认的对象遍历,就是逐个的获得对象中的属性(属性名和属性值);

  2.自定义对象遍历

  实现自定义对象遍历的前提:需要实现PHP预定义接口"Iterator"

  自定义对象遍历的概念:当遍历一个对象时,PHP自动按顺序执行预定义接口Iterator中实现的五个方法。

<?php

class A implements Iterator{

    public $count=0;

    public function current(){
        echo ‘current<br/>‘;
    }

    public function key(){
        echo ‘key<br/>‘;
    }

    public function next(){
        echo ‘next<br/>‘;
    }

    public function rewind(){
        echo ‘rewind<br/>‘;
    }

    public function valid(){ 

        $this->count++;

        if( $this->count<4 ){
            echo ‘valid<br/>‘;
            return true;
        }else{
            return false;
        }
    }
}

$a1 = new A;
var_dump( $a1 ); echo ‘<hr/>‘;

foreach( $a1 as $k=>$v ){ 

}

小结:
  1. 第一次将会按照 rewind->valid->current->key->next这个顺序执行五个被实现的方法;
  2. 第二次以后会按照 valid->current->key->next这个顺序循环执行4个被实现的方法;

 (三) 对象序列化

  在PHP中,如果我们直接将(PHP八种数据类型)数据写入文件中,那么,除了字符串数据外,其他的数据都将会失真。

  概念:对象的序列化就是通过serialize函数将某个对象转换成一个具有固定信息格式的字符串。涉及的函数:serialize(对象) 将对象进行序列化

<?php

class DirTool{
    public $path;
    public $resource;

    public function __construct(){
        $this->path = ‘./dir‘;
        $this->resource = opendir($this->path);
    }
}

$d = new DirTool;
var_dump( $d ); echo ‘<hr/>‘;

//将$d对象进行序列化,获得序列化之后的字符串结果
$str = serialize($d);
var_dump( $str ); 

小结:

  1. 经过序列化之后的对象,变成了一个具有一定格式的字符串。
  2. 资源类型的数据即使序列化之后也会失真,所以一般我们在对对象进行序列化的时候,会把资源类型的数据排除在外

  2.__sleep魔术方法

<?php

class DirTool{
    public $path;
    public $resource;

    public function __construct(){
        $this->path = ‘./dir‘;
        $this->resource = opendir($this->path);
    }

    //__sleep魔术方法   当基于该类的对象被序列化的时候,__sleep魔术方法将被触发执行
    public function __sleep(){
        //echo 100;
        return [‘path‘];//不在数组中的属性名,将会被排除在序列化操作之外
    }
}

$d = new DirTool;
var_dump( $d ); echo ‘<hr/>‘;

//将$d对象进行序列化,获得序列化之后的字符串结果
$str = serialize($d);
var_dump( $str ); 

小结

  1. PHP不负责定义__sleep魔术方法,只负责调用该魔术方法;
  2. 调用该魔术方法的时机是:当使用serialize函数序列化一个对象时,该类中的__sleep魔术方法将会被触发自动执行;
  3. 在__sleep魔术方法中,可以同return语句指定乃个属性应该参与到序列化的过程中来,不在数组中的属性都将被排除在序列化的过程之外;

  (四) 对象的反序列化

  概念:对象的反序列化就是通过unserialize函数将某个对象序列化后的字符串还原回原来的对象。涉及的函数:unserialize(序列化后的字符串) 将对象进行反序列化

<?php

$str = ‘O:7:"DirTool":2:{s:4:"path";s:5:"./dir";s:8:"resource";i:0;}‘;
//将序列化后的字符串进行反序列化,还原回对象
$obj = unserialize($str);

var_dump( $obj ); 

小结:我们从效果上看,虽然反序列化回了对象,但是找错了所属的类,这是因为在反序列化的过程中,需要有一个条件,那就是,必须存在这个对象的原始类的定义,即要在序列化的同一个php文件中进行

<?php

class DirTool{
    public $path;
    public $resource;

    public function __construct(){
        $this->path = ‘./dir‘;
        $this->resource = opendir($this->path);
    }
}

$str = ‘O:7:"DirTool":2:{s:4:"path";s:5:"./dir";s:8:"resource";i:0;}‘;
//将序列化后的字符串进行反序列化,还原回对象
$obj = unserialize($str);

var_dump( $obj ); 

小结:

  1. 我们可以使用unserialize函数对序列化后的字符串结果进行反序列化;
  2. 反序列化有一个前提,在反序列化的过程中,必须存在该对象的原始类的定义,否则将会把还原的对象归到一个系统类__PHP_Incomplete_Class下;
<?php

class DirTool{
    public $path;
    public $resource;

    public function __construct(){
        $this->path = ‘./dir‘;
        $this->resource = opendir($this->path);
    }

    //__wakeup魔术方法
    public function __wakeup(){
        $this->resource = opendir($this->path);
    }
}

//$str = ‘O:7:"DirTool":2:{s:4:"path";s:5:"./dir";s:8:"resource";i:0;}‘;
$str = ‘O:7:"DirTool":1:{s:4:"path";s:5:"./dir";}‘;
var_dump(unserialize($str));

小结

  1. 我们在__wakeup魔术方法中所作的操作,其实就是将之前排除的属性重新进行赋值操作;
  2. PHP不负责定义__wakeup魔术方法,只负责调用该魔术方法;
  3. 调用该魔术方法的时机是:当使用unserialize函数反序列化一个字符串时,该类中的__wakeup魔术方法将会被触发自动执行;

 

  (五) 命名空间

  

#关键字为namespace
namespace  空间名; 

注意事项:命名空间首次定义之前不能有任何PHP非注释代码;

  命名空间的使用

<?php

namespace first;

function f1(){
    echo 100;
}

namespace second;

function f1($v1){
    echo 200;
}

f1();//就近原则,不限定名称访问\first\f1();// 限定命名空间的访问

echo ‘嘿嘿嘿嘿,能看到我么‘; 

  

  命名空间的引入

//空间的引入,接上一个方法
use \first;f1();

小结 :

  1.命名空间都是在全局空间下的

  2.命名空间如果需要用到另外的空间需要用use引入才可以使用

原文地址:https://www.cnblogs.com/learningPHP-students2018/p/10201425.html

时间: 2024-10-04 00:52:28

面向对象(四)的相关文章

学java教程之面向对象(四)

学编程吧学java教程之面向对象(四)发布了,欢迎通过xuebiancheng8.com来访问 本次课来分析java面向对象之构造方法.什么是构造方法呢,构造方法听名字顾名思义,构造的时候执行的方法就叫构造方法. 没错,构造方法就是在构造对象的时候执行的方法,就是构造方法,那什么时候构造对象呢,是不是在new的时候调用构造对象呢,所以构造方法就是在new对象的时候执行的方法就是构造方法.构造方法一般用来为对象赋初值.完成对象的初始化. 下面我们来看如何定义构造方法. public class P

厘清面向对象四种模式:工厂模式、构造函数模式、原型模式、混合模式

面向对象是一种方法,用来封装功能,方便日后使用,避免大量的重复工作 一.工厂模式 (一)实现方法:在函数内创建一个对象并给对象赋予属性及方法,最终将对象返回. 1 function cPerson(name,sex,age){ 2  var o = new Object(); 3  o.name = name; 4  o.sex = sex; 5  o.age = age; 6  o.show = function(){ 7  console.log(this.name,this.age,thi

PHP面向对象(四)

引子: 1 <?php 2 //值传递 3 $a=10; 4 $b=$a; //将变量a的值取出复制一份赋给变量b 5 $b=20; 6 echo $a; //10 7 8 //引用传递 9 $a=10; 10 $b=&$a; //为变量a起个别名b 11 $b=20; 12 echo $a; //20 13 ?> 由引子程序可以看到,当使用"="号时是值传递,两个变量相对独立,改变其中一个,另一个不会发生影响:当在变量前加上"&"符时,

面向对象四

java:数据和操作结合在一起 一个类的成员变量会自动赋初始值 方法里面的成员变量为局部变量 “OO”:面向对象 函数:复用.单一性 1.对象是存在的具体实体,具有明确定义的特征和行为 2.万物皆对象,对象因我关注而产生 3.结构化编程:以解决问题为中心的设计的程序:面向对象:围绕着要解决的问题中的对象来设计 面向对象:一种认识事物的方式,注重对事物整体的认识,最符合人类自然的思维习惯 类和对象的关系:1.类是具有相同属性和行为的一组对象的集合 2.在软件系统中,我们用类来模拟现实生活中的实体

VC++ 之 第八课 面向对象(四)

这节讲什么是内联函数,为什么要使用内联函数? 当编译器发现某段代码在调用一个内联函数时,它不是去调用该函数,而是将该函数的代码,整段插入到当前位置.这样做的好处是省去了调用的过程,加快程序运行速度.(函数的调用过程,由于有前面所说的参数入栈等操作,所以总要多占用一些时间).这样做的不好处:由于每当代码调用到内联函数,就需要在调用处直接插入一段该函数的代码,所以程序的体积将增大.拿生活现象比喻,就像电视坏了,通过电话找修理工来,你会嫌慢,于是干脆在家里养了一个修理工.这样当然是快了,不过,修理工住

python学习之面向对象(四)

6.9 反射 反射是非常重要的内置函数之一. 反射是通过字符串去操作对象相关的属性,这里的对象包括:实列,类,当前模块,其他模块. 主要的四个函数: 查看: hasattr(对象,待查内容的字符串形式) 判断有没有,返回True或者False 获取: getattr(对象,要获取的内容的字符串形式,获取不到时的返回值) 增加: setattr(对象,要增加的内容的字符串形式) 删除: delattr(对象,要'删除的内容的字符串形式) 6.9.1 实例化中使用 class LOL: place

Java学习之面向对象四

1.构造方法的格式是什么?有哪些注意事项?  权限修饰符 类名(参数列表){方法体} 注意事项: ? 构造方法没有返回值类型.也不需要写返回值.因为它是为构建对象的,对象创建完,方法就执行结束. ? 构造方法名称必须和类型保持一致.   ? 构造方法没有具体的返回值. 2.构造方法可以重载吗? 里边可以有return语句吗?    可以重载 可以有return,但不能有返回. 3.给成员变量赋值有几种方式?有什么区别? get/set 直接赋值 带参构造器赋值 初始化 static 代码块赋值

疯狂java学习笔记之面向对象(四) - this关键字

Java中this关键字主要有以下两个方法: 1.this引用 - 可用于任何非static修饰的方法和构造器中,当this用于方法中时,它代表调用该方法的实例/对象;当this用于构造器中时,它代表构造器正在初始化的实例/对象 2.this调用 - 只能在构造器的第一行出现. 如何区分this引用与this调用呢? this引用写法为:this.  ;  而this调用写法为:this(); 例1: 1 class TestThis{ 2 private double weight; 3 pr

python 面向对象四 继承和多态

一.继承 1 class Animal(object): 2 def run(self): 3 print('Animal is running...') 4 5 class Dog(Animal): 6 7 def run(self): 8 print('Dog is running...') 9 10 def eat(self): 11 print('Eating meat...') 12 13 dog = Dog() 14 dog.run() 1 Dog is running... 当子类