• php面向对象高级-魔术方法与迭代器


    1,魔术方法__set与__get, __call

    >这些魔术方法,将在相关的属性或者方法不存在时调用

    >函数原型

      .function __set( $property, $value ):传递属性的名字和新的值

      .function __get( $property ):传递属性的名字,并且返回属性的值

      .function __call( $methods, $args ):传递方法的名字和一个数字索引的数组,数组包含传递的参数,第一个参数的索引是0

     1 class Coordinate {
     2         private $arr = array( 'x' => null, 'y' => null );
     3         function __get( $property ) {
     4             if( array_key_exists( $property, $this->arr ) ){
     5                 return $this->arr[$property];
     6             }else {
     7                 print "不能访问一个不存在的键名" . PHP_EOL;
     8             }
     9         }
    10         function __set( $property, $value ) {
    11             if( array_key_exists( $property, $this->arr ) ) {
    12                 $this->arr[$property] = $value;
    13             }else {
    14                 print "不能设置一个不存在的键名" . PHP_EOL;
    15             }
    16         }
    17     }
    18     
    19     $obj = new Coordinate();
    20     $obj->x = 10;
    21     echo $obj->x . PHP_EOL;
    22     $obj->n = 20;
    23     echo $obj->n . PHP_EOL;

    2,__call的应用

    >通过__call可以使HelloWorldDelegator的实例调用HelloWorld的任意存在的方法

     1 class HelloWorld {
     2         function display( $count ){
     3             for( $i = 0 ; $i < $count; $i++ ) {
     4                 echo "Hello World $i " . PHP_EOL;
     5             }
     6             return $count;
     7         }
     8     }
     9 
    10     
    11     class HelloWorldDelegator {
    12         private $obj;
    13         function __construct(){
    14             $this->obj = new HelloWorld();
    15         }
    16         function __call( $method, $args ) {
    17             return call_user_func_array( array( $this->obj, $method ), $args );
    18         }
    19     }
    20 
    21     $obj = new HelloWorldDelegator();
    22     print $obj->display( 3 );
    23     print PHP_EOL;
    24     
    25     $obj->show();

    3,迭代

    >实现一个自己的迭代器,可以通过实现Iterator接口

    Iterator接口原型:

    Iterator extends Traversable {
    /* Methods */
    abstract public mixed current ( void )
    abstract public scalar key ( void )
    abstract public void next ( void )
    abstract public void rewind ( void )
    abstract public bool valid ( void )
    }
     1 class NumberSquared implements Iterator {
     2     private $start;
     3     private $end;
     4     private $cur;
     5 
     6     function __construct ( $start, $end ){
     7         $this->start = $start;
     8         $this->end = $end;
     9     }
    10     function rewind(){ 
    11         $this->cur = $this->start;
    12     }
    13     function key(){
    14         return $this->cur;
    15     }
    16     function current(){
    17         return pow( $this->cur, 2 );
    18     }
    19     function next(){
    20         $this->cur++;
    21     }
    22     function valid(){
    23         return $this->cur <= $this->end;
    24     }
    25 }    
    26 
    27 $obj = new NumberSquared( 3, 9 );
    28 foreach( $obj as $key => $value ){
    29     print "the square of $key is $value" . PHP_EOL;
    30 }

    类本身一般用来表示数据和拥有与这些数据的交互方法,所以一般不需要一个纯粹的类迭代器,我们可以实现另一个接口:IteratorAggregate,接口摘要如下:

    IteratorAggregate extends Traversable {
    /* Methods */
    abstract public Traversable getIterator ( void )
    }

    这个接口只有一个方法,作用是创建一个外部的迭代器接口

    改造后的迭代,实现了迭代器与数据处理的分离:

     1 class NumberSquared implements IteratorAggregate {
     2     private $start;
     3     private $end;
     4 
     5     function __construct( $start, $end ) {
     6         $this->start = $start;
     7         $this->end = $end;
     8     }
     9 
    10     function getIterator(){
    11         return new NumberSquaredIterator( $this );
    12     }    
    13 
    14     function getStart(){
    15         return $this->start;
    16     }
    17 
    18     function getEnd(){ 
    19         return $this->end;
    20     }
    21 }
    22 
    23 class NumberSquaredIterator implements Iterator {
    24     private $cur;
    25     private $obj;
    26     function __construct( $obj ) {
    27         $this->obj = $obj;
    28     }
    29     function rewind(){ 
    30         $this->cur = $this->obj->getStart();
    31     }
    32     function key(){
    33         return $this->cur;
    34     }
    35     function next(){
    36         $this->cur++;
    37     }
    38     function current(){
    39         return pow( $this->cur, 2 );
    40     }
    41     function valid(){
    42         return $this->cur <= $this->obj->getEnd();
    43     }
    44 }
    45 
    46 $obj = new NumberSquared( 3, 9 );
    47 foreach( $obj as $key => $value ) {
    48     print "the $key is $value " . PHP_EOL;
    49 }
  • 相关阅读:
    C# 递归查找树状目录
    C#递归计算树形菜单
    使用StringBuilder写XML遭遇UTF-16问题
    Error: 'The service did not respond in a timely fashion'
    no suitable method found to override
    Could not load file or assembly "win32_x86dotnet1crdb_adoplus.dll' or one of its dependencies.
    Unable to find the requested .Net Framework Data Provider
    Call JMS Web Service
    Remove Mapping
    卸载windows服务
  • 原文地址:https://www.cnblogs.com/ghostwu/p/8459604.html
Copyright © 2020-2023  润新知