为什么我不能在PHP中重载构造函数?
我已经放弃了所有能够在PHP中重载我的构造函数的希望,所以我真正想知道的是为什么 。
有甚么理由呢? 它创build固有的错误代码? 是不是被广泛接受的语言devise不允许它,或者比PHP更好的其他语言?
您可以使用可变参数来产生相同的效果。 如果没有强大的打字function,在给定默认参数和所有其他“解决方法”的情况下,添加并没有什么意义。
你不能在PHP中重载任何方法。 如果您希望能够在传递几个不同的参数组合的同时实例化一个PHP对象,请使用具有私有构造函数的工厂模式。
例如:
public MyClass { private function __construct() { ... } public static function makeNewWithParameterA($paramA) { $obj = new MyClass(); // other initialization return $obj; } public static function makeNewWithParametersBandC($paramB, $paramC) { $obj = new MyClass(); // other initialization return $obj; } } $myObject = MyClass::makeNewWithParameterA("foo"); $anotherObject = MyClass::makeNewWithParametersBandC("bar", 3);
真正的重载在PHP中确实不受支持。 正如@Pestile提到的,你可以使用可变参数。 有些人只是使用各种选项的关联数组来解决这个问题。
为了完整性,我会build议Fluent接口 。 这个想法是通过添加return $this;
到您的方法的结尾,您可以将呼叫链接在一起。 所以,而不是
$car1 = new Car('blue', 'RWD'); $car2 = new Car('Ford', '300hp');
(这根本行不通),你可以这样做:
$car = (new Car) ->setColor('blue') ->setMake('Ford') ->setDrive('FWD');
这样,你可以select你想要设置的属性。 在很多方面,它类似于将一些选项传递给你的初始调用:
$car = new Car(['make' => 'Ford', 'seats' => 5]);
他们说这个工作:
<?php class A { function __construct() { $a = func_get_args(); $i = func_num_args(); if (method_exists($this,$f='__construct'.$i)) { call_user_func_array(array($this,$f),$a); } } function __construct1($a1) { echo('__construct with 1 param called: '.$a1.PHP_EOL); } function __construct2($a1,$a2) { echo('__construct with 2 params called: '.$a1.','.$a2.PHP_EOL); } function __construct3($a1,$a2,$a3) { echo('__construct with 3 params called: '.$a1.','.$a2.','.$a3.PHP_EOL); } } $o = new A('sheep'); $o = new A('sheep','cat'); $o = new A('sheep','cat','dog'); // results: // __construct with 1 param called: sheep // __construct with 2 params called: sheep,cat // __construct with 3 params called: sheep,cat,dog ?>
而且似乎每个人都对此感到满意,但是对我而言,这是行不通的。如果你把它运用起来,那么它也是一种超载…
它采取所有的议会,并将其传递给二级函数构造函数…
我真的没有面向对象的专家,但据我所知, 过载意味着一个方法的能力取决于它接收的参数作为input不同的行为。 这对于PHP来说是非常有可能的,你不需要声明inputtypes,因为PHP没有强大的input,而且所有的重载都是在运行时完成的,而不是编译时间。
您可以在构造函数中使用条件语句,然后执行您的任务。 例如。
class Example { function __construct($no_of_args) {// lets assume 2 switch($no_of_args) { case 1: // write your code break; case 2: //write your 2nd set of code break; default: //write your default statement } } } $object1 = new Example(1); // this will run your 1st case $object2 = new Example(2); // this will run your 2nd case
等等…
PHP手册:函数参数,默认值
我简单地通过使用函数参数的默认值来克服这个问题。 在__constuct
,首先列出所需的参数。 以通用格式$param = null
列出可选参数。
class User { private $db; private $userInput; public function __construct(Database $db, array $userInput = null) { $this->db = $db; $this->userInput = $userInput; } }
这可以被实例化为:
$user = new User($db)
要么
$user = new User($db, $inputArray);
这不是一个完美的解决scheme,但是我已经通过将参数分隔成绝对必要的参数来完成这个工作,不pipe何时构build对象,并且作为一个组, 按照重要性排列的可选参数 。
有用。
据我所知,PHP中的构造函数重载是不允许的,只是因为PHP的开发者没有包含这个function – 这是关于PHP的许多抱怨之一。
我听说过技巧和解决方法,但是在OOP意义上真正的重载缺失。 也许在未来的版本中,它将被包括在内。
我想我们也可以使用默认参数的构造函数作为PHP中构造函数重载的潜在替代。
不过,真正令人伤心的是PHP中不支持真正的构造函数重载。
<?php //php do not automatically call parent class constructor at all if child class has constructor so you have to call parent class constructor explicitly, however parent class constructor is called automatically if child class has no constructor class MyClass { function construct1($value1) { echo "<br/> dummy constructor is called with 1 arguments and it is $value1"; } function construct2($value1,$value2) { echo "<br/> dummy constructor is called with 2 arguments and it is $value1, $value2"; } function construct3($value1,$value2,$value3) { echo "<br/> dummy constructor is called with 3 arguments and it is $value1, $value2 , $value3"; } public function __construct() { $NoOfArguments = func_num_args(); //return no of arguments passed in function $arguments = func_get_args(); echo "<br/> child constructor is called $NoOfArguments"; switch ($NoOfArguments) { case 1: self::construct1($arguments[0]); break; case 2: self::construct2($arguments[0],$arguments[1]); break; case 3: self::construct3($arguments[0],$arguments[1],$arguments[2]); break; default: echo "Invalid No of arguments passed"; break; } } } $c = new MyClass(); $c2 = new MyClass("ankit"); $c2 = new MyClass("ankit","Jiya"); $c2 = new MyClass("ankit","Jiya","Kasish");
?>