Можно ли перегрузить конструкторы в PHP?
Это вымышленный пример, он становится намного полезнее, когда параметров много.
Это позволит вызывающей стороне использовать либо new Person("Jim", 1950, 10, 2)
или же new Person("Jim", datetimeobj)
, Я знаю о необязательных параметрах, это не то, что я ищу здесь.
В C# я могу сделать:
public Person(string name, int birthyear, int birthmonth, int birthday)
:this(name, new DateTime(birthyear, birthmonth, birthday)){ }
public Person(string name, DateTime birthdate)
{
this.name = name;
this.birthdate = birthdate;
}
Могу ли я сделать подобное в PHP? Что-то вроде:
function __construct($name, $birthyear, $birthmonth, $birthday)
{
$date = new DateTime("{$birthyear}\\{$birthmonth}\\{$birthyear}");
__construct($name, $date);
}
function __construct($name, $birthdate)
{
$this->name = $name;
$this->birthdate = $birthdate;
}
Если это невозможно, что является хорошей альтернативой?
2 ответа
Для этого я бы использовал именованные / альтернативные конструкторы / фабрики или как угодно, как вы хотите их называть:
class Foo {
...
public function __construct($foo, DateTime $bar) {
...
}
public static function fromYmd($foo, $year, $month, $day) {
return new self($foo, new DateTime("$year-$month-$day"));
}
}
$foo1 = new Foo('foo', $dateTimeObject);
$foo2 = Foo::fromYmd('foo', 2012, 2, 25);
Должен быть один канонический конструктор, но у вас может быть столько альтернативных конструкторов, сколько и вспомогательных упаковщиков, которые все ссылаются на канонический. Или вы можете установить альтернативные значения в этих альтернативных конструкторах, которые вы обычно не устанавливаете в обычных:
class Foo {
protected $bar = 'default';
public static function withBar($bar) {
$foo = new self;
$foo->bar = $bar;
return $foo;
}
}
Это не совсем то же самое, но вы можете манипулировать количеством аргументов в конструкторе, подсчитывать их или проверять их типы и вызывать соответствующие функции. Как пример:
class MultipleConstructor {
function __construct() {
$args = func_get_args();
$construct = '__construct' . func_num_args();
if (method_exists($this, $construct))
call_user_func_array(array($this, $construct), $args);
}
private function __construct1($var1)
{
echo 'Constructor with 1 argument: ' . $var1;
}
private function __construct2($var1, $var2)
{
echo 'Constructor with 2 arguments: ' . $var1 . ' and ' . $var2;
}
}
$pt = new MultipleConstructor(1);
$pt = new MultipleConstructor(2,3);