2017-03-23 1 views
0

Betrachten Sie die folgenden Klassen:Strikter Typ Hinting für überschriebene Elternmethode?

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); 
    } 

} 

Dies erzeugt die follwing Fehler: Erklärung attachmentCollection :: add() sollte mit Object kompatibel sein :: add ($ object)

Wenn man sich anschaut, der Code, ich denke, es ist ziemlich offensichtlich, was ich versuche zu tun. Ich möchte die attachmentCollection im Wesentlichen die gleiche sein wie die objectCollection, außer dass die Objekte, die hinzugefügt werden können (oder entfernt) müssen eine Instanz von attachment sein.

Was ist der richtige Weg?

+0

soweit Ich weiß, PHP unterstützt keine Überladung in der gleichen Weise, wie es von höheren Sprachen getan wird ... die müssen die gleiche Signatur haben ... –

+0

Oh, ok. Das ist schade. – minychillo

Antwort

0

PHP errored code

PHP working code

Ändern Sie diese zu

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; 
    } 

Diese

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; 
    } 
+0

Vielen Dank für Ihre Antwort! Natürlich wird dadurch der Fehler behoben, aber ich könnte andere Klassen aus der objectCollection mit anderen Typhinweisen erweitern. Wie eine 'productCollection' zum Beispiel, wo die 'add' Methode nur 'product' Objekte akzeptiert – minychillo

+0

@minychillo Wenn Sie 'strict_types' verwenden, müssen Sie es auch in Elternklassen folgen. –

0

Wenn niemand eine bessere Lösung hat, hier ist das, was ich ging mit (noch offen für eine bessere Lösung):

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); 
    } 

} 
0

im Fall, dass Sie weitere Klassen von der Objektklasse und die Verfahren sollten kompatibel sein verlängern, dann würde ich empfehlen eine Schnittstelle als übergebenen Parameter zu verwenden, zum Beispiel:

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 
}