Faire d'un objet superclasse devenir un objet sous-classe en PHP5
-
06-07-2019 - |
Question
<?php
class A{
//many properties
protected $myProperty1;
protected $myProperty2;
protected $myProperty3;
public function __construct(){
$this->myProperty1='some value';
$this->myProperty2='some value';
$this->myProperty3='some value';
}
public function getProperty1(){
return $this->myProperty1;
}
public function getProperty2(){
return $this->myProperty2;
}
public function getProperty3(){
return $this->myProperty3;
}
//edited: I added some setters, meaning that the object returned from the functions may already have these properties altered
public function setProperty1($p){
$this->myProperty1=$p;
}
public function setProperty2($p){
$this->myProperty2=$p;
}
public function setProperty3($p){
$this->myProperty3=$p;
}
}
class B extends A{
private $myProperty4;
public function __construct(A $a){
$this=$a; //this line has error,it says $this cannot be re-assigned
$this->myProperty4='some value';
}
public function getProperty4(){
return $this->myProperty4;
}
}
//$a = new A();
$a = someClass::getAById(1234); //edited: $a is returned by a function (I cannot modify it)
$b= new B($a); //error
?>
J'aimerais créer un objet B en passant un objet A au constructeur de B, comme vous pouvez le constater, je ne peux pas réaffecter la variable $ this. Je ne suis pas autorisé à modifier la classe A, quand il y a beaucoup de propriétés dans A, il serait fastidieux de faire de telles choses dans le constructeur de B:
public function __construct(A $a){
parent::__construct();
$this->myProperty1=$a->getProperty1();
$this->myProperty2=$a->getProperty2();
$this->myProperty3=$a->getProperty3();
$this->myProperty4='some value';
}
Ma question est la suivante: comment créer un objet de classe B en toute sécurité en utilisant un objet A avec un minimum de codage?
La solution
class A
{
public $property = 'Foobar';
}
class B extends A
{
public function __construct()
{
echo $this->property; // Foobar
}
}
Est-ce que je manque quelque chose? On dirait que vous essayez de forcer la POO à faire quelque chose que ce n’est pas prévu, ou que vous avez du mal à comprendre l’héritage.
Chaque méthode et propriété publique ou protégée de la classe A est disponible dans la classe B. Soit en la référant directement (comme dans mon exemple), soit en utilisant la syntaxe parent ::.
EDIT
(Question clarifiée par l'auteur)
Si les propriétés de la classe A sont accessibles, vous pouvez utiliser l'une des méthodes suivantes pour les copier dans la classe B
class B
{
public function __construct()
{
$a = new A(); // Or however A is instantiated
foreach(get_object_vars($a) as $key => $value)
{
$this->$key = $value;
}
}
}
Autres conseils
Puisque B étend A, pourquoi ne pas simplement créer B pour commencer? Si vous devez initialiser des propriétés supplémentaires, vous pouvez remplacer le constructeur de la manière suivante:
class B extends A {
public function __construct(){
parent::__construct(); //calls A's constructor
$this->Bproperty='somevalue';
}
}
Si cela ne suffit pas, vous voudrez peut-être examiner Reflection.