PHP迭代模式的Iterator和IteratorAggregate

来源:互联网 发布:淘宝店主图图片尺寸 编辑:程序博客网 时间:2024/06/07 00:35

使用迭代模式遍历所有的对象的时候,都必须实现Traversable(遍历)接口。但是Traversable是一个内部的类,只有用c语言编写的类才可以实现Traversable实现。如果我们在自定义的 类中实现它,会报错。那么我们要实现对象的遍历,就必须通过Iterator或者IteratorAggregate接口实现Traversable接口。
一,首先说说Iterator接口:它是在c语言中定义的,都是抽象方法,所以我们在实现接口的时候,就必须定义这些方法,代码如下:
    Iterator extends Traversable {    /* 方法 */    abstract public mixed current ( void )    abstract public scalar key ( void )    abstract public void next ( void )    abstract public void rewind ( void )    abstract public boolean valid ( void )   }

接着我们在PHP中实现接口Iterator,代码如下:

     //自定义类实现接口Iteratorclass myIterator implements Iterator {    private $position = 0;    private $array = array(        "firstelement",        "secondelement",        "lastelement",    );      public function __construct() {        $this->position = 0;    }    //定义rewind()-将数组指针移动到数组的开头位置    function rewind() {        var_dump(__METHOD__);        $this->position = 0;    }    //定义current()-返回当前的值    function current() {        var_dump(__METHOD__);        return $this->array[$this->position];    }    //定义可以key()-返回当前的键值    function key() {        var_dump(__METHOD__);        return $this->position;    }    //定义next()-将数组指针向前进一位指向下一个数组元素    function next() {        var_dump(__METHOD__);        ++$this->position;    }    //定义valid()-确定当前元素是否存在,并且必须在next()和rewind()方法之后才可以调用    function valid() {        var_dump(__METHOD__);        return isset($this->array[$this->position]);    }}$it = new myIterator;foreach($it as $key => $value) {    var_dump($key, $value);    echo "\n";}

代码运行结果如下:

大家可能不明白,为什么利用foreach()就可以循环打印出类的属性,程序执行的顺序看我的注释,再次提醒大家注意
“定义valid()-确定当前元素是否存在,并且必须在next()和rewind()方法之后才可以调用”。


string(18) "myIterator::rewind" ----------程序开始执行首先调用rewind()函数,将数组指针移到数组开头位置
string(17) "myIterator::valid" ----------接着调用valid()当前元素是否存在,这个函数每次紧跟rewind()和next()函数被调用
string(19) "myIterator::current" ----------调用current()获取当前的值
string(15) "myIterator::key" ----------调用key()获取当前位置的键值
int(0)
string(12) "firstelement"

string(16) "myIterator::next" ----------上一步获取当前位置,肯定要调用next(),获取下一个位置的指针,即指针向下移动
string(17) "myIterator::valid" ----------判断当前元素是否存在
string(19) "myIterator::current" ----------如果存在,获取当前元素
string(15) "myIterator::key" ----------获取当前键值,为了下一步指针向前移动
int(1)
string(13) "secondelement"

string(16) "myIterator::next" ---------指针指向下一个元素
string(17) "myIterator::valid" ---------判断当前元素是否存在
string(19) "myIterator::current" ---------元素存在,获取当前的元素
string(15) "myIterator::key" ---------获取当前键值
int(2)
string(11) "lastelement"

string(16) "myIterator::next" ---------指针指向下一个位置
string(17) "myIterator::valid" ---------判断当前位置是否有值。如果有获取值,没有就结束遍历


二 ,IteratorAggregate接口(是用来将Iterator接口要求实现的5个方法委托给其他类(比如ArrayIterator)来实现)
(1) ArrayIterator接口:允许从PHP数组中创建一个迭代器。上面我们通过实现Iterator接口实现迭代器,但是ArrayIterator可以直接跳过,实现同样的功能。

(2)当ArrayIterator迭代器和IteratorAggregate类一起使用的时候,直接免去Iterator创建方法的工作,所以在实现IteratorAggregate类中的方法getIterator时候,返回一个ArrayIterator接口就好。
(3) IteratorAggregate的c语言实现代码:定义抽象方法getIterator,所以实现接口的时候,必须定义该方法
             IteratorAggregate extends Traversable {                    /* 方法 */                 abstract public Traversable getIterator ( void )                   }

//测试代码如下:class myData implements IteratorAggregate {    public $property1 = "Public property one";    public $property2 = "Public property two";    public $property3 = "Public property three";    public function __construct() {        $this->property4 = "last property";    }    //定义方法----getIterator()---返回一个Iterator类的实例    public function getIterator() {//ArrayIterator()接口可以创建一个Iterator实例        return new ArrayIterator($this);    }}$obj = new myData();foreach($obj as $key => $value) {    var_dump($key, $value);    echo "\n";}


运行如下:
string(9) "property1"
string(19) "Public property one"

string(9) "property2"
string(19) "Public property two"

string(9) "property3"
string(21) "Public property three"

string(9) "property4"
string(13) "last property"


/******************************************希望帮助到大家,解决你们的问题************************************************************/

1 0
原创粉丝点击