一个对象的属性(也不能说是遍历对象的属性,遍历什么,还得看current函数里面写的是什么。)可以用foreach()循环进行迭代遍历:
任何实现Traversable接口的类都可以用foreach结构遍历。但是,Traversable是一个空的接口而且不能被直接执行;反之,你可以执行Iterator或者IteratorAggregate,它们都是从Traversable继承而来。
主要的接口是Iterator,接口的主要方法如下:
void rewind() | 重新把迭代器指向列表的开始处(这个在执行时并不总是可用的) |
mixed current() | 返回当前位置的值 |
mixed key() | 返回当前位置的关键字 |
void next() | 把迭代器移动到下一个关键字/值对 |
bool valid() | 返回true/false值,判断是否还有更多的值(在调用current()和key()之前使用) |
<?php class NumberSquared implements Iterator{ public function __construct($start,$end){ $this->start=$start; $this->end=$end; } public function rewind(){ $this->cur=$this->start; } public function key(){ return $this->cur; } public function current(){ return pow($this->cur,2); } public function next(){ $this->cur++; } public function valid(){ return $this->cur <= $this->end; } private $start,$end; private $cur; } $obj=new NumberSquared(3,7); foreach($obj as $key => $value){ print "The square of $key is $value <br>"; } ?>
目前在许多情况下,类本身将表示数据和拥有与这些数据交互的方法。事实上,需要一个迭代器可能不是它的主要目的。另外,当迭代遍历一个对象的时候,迭代的状态(当前的位置)通常会存储在对象本身,因此不允许迭代的嵌套。所以,可以让类实现IteratorAggregate接口从而把类的执行和它的迭代其分离开来。
下面是例子代码:
<?php class NumberSquared implements IteratorAggregate{ public function __construct($start,$end){ $this->start=$start; $this->end=$end; } public function getIterator(){ return new NumberSquaredIterator($this); } public function getStart(){ return $this->start; } public function getEnd(){ return $this->end; } private $start,$end; } class NumberSquaredIterator implements Iterator{ function __construct($obj){ $this->obj=$obj; } public function rewind(){ $this->cur=$this->obj->getStart(); } public function key(){ return $this->cur; } public function current(){ return pow($this->cur,2); } public function next(){ $this->cur++; } public function valid(){ return $this->cur <= $this->obj->getEnd(); } private $obj; private $cur; } $obj=new NumberSquared(3,7); foreach($obj as $key => $value){ print "The square of $key is $value <br>"; } ?>
两个例子的执行方法都一样,IteratorAggregate接口可以让类的主要功能与迭代遍历需要的方法分离到两个独立的实体中。
为什么这样做,现在我还不是特别能体会和理解。