为什么我不能在PHP中重载构造函数?

tom*_*tom 96 php oop constructor overloading

我已经放弃了所有希望能够在PHP中重载我的构造函数,所以我真正想知道的是为什么.

有没有理由呢?它是否会产生固有的错误代码?它是否被广泛接受的语言设计不允许它,或者其他语言比PHP更好?

Ale*_*ein 132

你不能在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);
Run Code Online (Sandbox Code Playgroud)

  • +1对于清洁,这种方法清楚地说明了你想要实现的目标,对我来说更清洁. (14认同)
  • 这不违反单一责任原则吗?你正在创建你的课程(一个职责),你也在做各种类功能(你的主要职责).在现实世界中你可能需要从外部来源读取一些$参数,即数据库,这又创造了另一个责任. (4认同)
  • 我是PHP的新手 - 已经完成了大量的Java:HOLY限制蝙蝠侠!您的示例甚至不遵循工厂模式.https://en.wikipedia.org/wiki/Factory_method_pattern (3认同)
  • @Chrisian 这是一个静态工厂方法。有关工厂的更多一般信息,请参阅 [Factory(面向对象编程)](https://en.wikipedia.org/wiki/Factory_(object-oriented_programming))。它们实际上是任何创建对象而不是使用 `new` 的东西。 (3认同)
  • 正如@JDSandifer 所说,这是一家工厂。如果有人不喜欢干净代码的“静态工厂”,你总是可以创建一个包含 `makeNewWithParameterA()` 和 `makeNewWithParametersBandC()` 的 `MyClassFactory` 对象而不是静态的,所以它们更适合“依赖注入”框架. 但是,如果您控制环境并且不想创建“工厂类”,这是最干净的方法,正如@SamGiles 所说。具有相同构造函数和 switch-case 来调用私有方法的解决方案是糟糕的代码。 (3认同)

pes*_*669 57

您可以使用变量参数来产生相同的效果.如果没有强类型,在给定默认参数和所有其他"解决方法"的情况下添加它没有多大意义.


Dom*_*nes 5

PHP中确实不支持真正的重载.正如@Pestilence所提到的,你可以使用变量参数.有些人只是使用各种选项的关联数组来克服这个问题.


Cod*_*key 5

为了完整起见,我建议使用Fluent接口。这个想法是,通过return $this;在方法的末尾添加代码,可以将调用链接在一起。所以代替

$car1 = new Car('blue', 'RWD');
$car2 = new Car('Ford', '300hp');
Run Code Online (Sandbox Code Playgroud)

(这根本行不通),您可以执行以下操作:

$car = (new Car)
       ->setColor('blue')
       ->setMake('Ford')
       ->setDrive('FWD');
Run Code Online (Sandbox Code Playgroud)

这样,您可以准确选择要设置的属性。在很多方面,这类似于将一系列选项传递给您的初始调用:

$car = new Car(['make' => 'Ford', 'seats' => 5]);
Run Code Online (Sandbox Code Playgroud)

  • 但这不是一成不变的,您可以使用无效状态实例化该类。 (4认同)

Ant*_*dge 5

PHP 手册:函数参数,默认值

我只是通过使用函数参数的默认值来克服这个问题。在 中__constuct,首先列出所需的参数。在一般形式之后列出可选参数$param = null

class User
{
    private $db;
    private $userInput;

    public function __construct(Database $db, array $userInput = null)
    {
        $this->db = $db;
        $this->userInput = $userInput;
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以实例化为:

$user = new User($db)
Run Code Online (Sandbox Code Playgroud)

或者

$user = new User($db, $inputArray);
Run Code Online (Sandbox Code Playgroud)

这不是一个完美的解决方案,但我已经通过将参数分成绝对强制参数来完成这项工作,无论对象何时构造,并且作为一个组,按重要性顺序列出可选参数

有用。