Consider the following to classes:
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);
}
}
This produces the follwing error: Declaration of attachmentCollection::add() should be compatible with objectCollection::add($object)
When you look at the code, I think it's rather obvious what I am trying to do. I want the attachmentCollection
to essentially be the same as the objectCollection
, except that the objects that can be added ( or removed ) need to be an instance of attachment
.
What is the right way to do this ?
Change this to
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;
}
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;
}
If nobody has a better solution, here is what I went with ( still open to a better solution ):
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);
}
}
in the case you want to extend further classes from the objectClass and the methods should be compatible, then i would recommend to use an Interface as the passed parameter, for example:
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
}