对于重写的父方法,更严格的类型提示?

时间:2017-03-23 08:48:04

标签: php inheritance type-hinting

考虑以下几类:

class objectCollection implements Iterator {

  private $objectArray = [];
  private $position = 0;


  public function __construct() {
      $this->position = 0;
  }

  public function add( $object ){
    if(!in_array( $object, $this->objectArray))
      $this->objectArray[] = $object;
    return $this;
  }

  public function remove( $object ){
    if(($key = array_search( $object, $this->objectArray())) !== false)
      unset($this->objectArray[$key]);
    return $this;
  }

  public function rewind() {
      $this->position = 0;
  }

  public function current() {
      return $this->objectArray[$this->position];
  }

  public function key() {
      return $this->position;
  }

  public function next() {
      ++$this->position;
  }

  public function valid() {
      return isset($this->objectArray[$this->position]);
  }

}

class attachmentCollection extends objectCollection {

  public function add( attachment $attachment ){
    return parent::add($attachment);
  }

  public function remove( attachment $attachment ){
    return parent::remove($attachment);
  }

}

这会产生以下错误: attachmentCollection :: add()声明应与objectCollection :: add($ object)

兼容

当你看代码时,我认为我想要做的事情显而易见。 我希望attachmentCollection基本上与objectCollection相同,只是可以添加(或删除)的对象需要是attachment的实例。

这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:0)

PHP errored code

PHP working code

将此更改为

public function add( $object ){
    if(!in_array( $object, $this->objectArray))
      $this->objectArray[] = $object;
    return $this;
  }


public function remove( $object ){
    if(($key = array_search( $object, $this->objectArray())) !== false)
      unset($this->objectArray[$key]);
    return $this;
  }

public function add(attachment $object ){
    if(!in_array( $object, $this->objectArray))
      $this->objectArray[] = $object;
    return $this;
 }
public function remove(attachment $object ){
    if(($key = array_search( $object, $this->objectArray())) !== false)
      unset($this->objectArray[$key]);
    return $this;
  }

答案 1 :(得分:0)

如果没有人有更好的解决方案,那么这就是我的目标(仍然需要更好的解决方案):

class attachmentCollection extends objectCollection {

  public function add( $attachment ){
    if(! $attachment instanceof attachment) throw new \Exception('Argument must be instance of attachment');
    return parent::add($attachment);
  }

  public function remove( $attachment ){
    if(! $attachment instanceof attachment) throw new \Exception('Argument must be instance of attachment');
    return parent::remove($attachment);
  }

}

答案 2 :(得分:0)

如果你想从objectClass扩展更多的类并且方法应该兼容,那么我建议使用Interface作为传递的参数,例如:

interface collection{     
   //your methods
}

class objectCollection implements Iterator {

    private $objectArray = [];
    private $position = 0;

    public function add(collection $object){
      if(!in_array( $object, $this->objectArray))                       
        $this->objectArray[] = $object;
        return $this;
    }

    public function remove(collection $object ){
       if(($key = array_search( $object, $this->objectArray())) !==false)
        unset($this->objectArray[$key]);
        return $this;
    }
  ....
}


 class attachmentCollection extends objectCollection {

    public function add(collection $attachment ){
       return parent::add($attachment);
    }

    public function remove( collection $attachment ){
       return parent::remove($attachment);
    }

 }

 class productCollection extends objectCollection {

     public function add(collection $attachment ){ 
        return parent::add($attachment);
     }

     public function remove(collection $attachment ){
         return parent::remove($attachment);
     }

 }


 class attachment  implements  collection {
    //implement interface methods
 }

class product implements collection{
   //implement interface methods 
 }