Заставить объект суперкласса стать объектом подкласса в PHP5
-
06-07-2019 - |
Вопрос
<?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
?>
Я хотел бы создать объект B, передав объект A конструктору B. Как вы видите, я не могу переназначить переменную $ this. Мне не разрешено изменять класс A, когда в A много свойств, мне было бы утомительно делать такие вещи в конструкторе B:
public function __construct(A $a){
parent::__construct();
$this->myProperty1=$a->getProperty1();
$this->myProperty2=$a->getProperty2();
$this->myProperty3=$a->getProperty3();
$this->myProperty4='some value';
}
У меня такой вопрос: как я могу безопасно создать объект класса B, используя объект A с минимальным количеством кода?
Решение
class A
{
public $property = 'Foobar';
}
class B extends A
{
public function __construct()
{
echo $this->property; // Foobar
}
}
Я что-то упустил? Звучит так, будто вы пытаетесь заставить ООП сделать то, что оно не предназначено, или у вас возникают проблемы с пониманием наследования. Р>
Каждый открытый или защищенный метод и свойство из класса A доступны в классе B. Либо путем прямой ссылки на него (как в моем примере), либо с использованием синтаксиса parent ::.
ИЗМЕНИТЬ
(автор уточнил вопрос)
Если свойства класса A доступны, вы можете использовать что-то вроде следующего, чтобы скопировать их в класс 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;
}
}
}
Другие советы
Поскольку B расширяет A, почему бы просто не создать B для начала? Если вам нужно инициализировать некоторые дополнительные свойства, вы можете переопределить конструктор следующим образом:
class B extends A {
public function __construct(){
parent::__construct(); //calls A's constructor
$this->Bproperty='somevalue';
}
}
Если этого недостаточно, вы можете посмотреть на Reflection.