Почему я не могу перегружать конструкторы в PHP?


Я оставил все надежды когда-либо быть в состоянии перегрузить мои конструкторы в PHP, так что я действительно хотел бы знать,почему.

есть ли вообще причина для этого? Создает ли он изначально плохой код? Является ли широко распространенным языковым дизайном, чтобы не допустить этого, или другие языки лучше, чем PHP?

12 81

12 ответов:

можно использовать переменные аргументы для получения того же эффекта. Без сильного ввода текста нет смысла добавлять, учитывая аргументы по умолчанию и все другие "обходные пути"."

вы не можете перегрузить какой-либо метод в 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. Как упоминалось в @Pestilence, вы можете использовать переменные аргументы. Некоторые люди просто используют ассоциативный массив различных вариантов, чтобы преодолеть это.

для полноты картины, я предлагаю Интерфейсы Свободно. Идея заключается в том, что путем добавления return $this; до конца ваших методов вы можете связывать вызовы вместе. Так что вместо

$car1 = new Car('blue', 'RWD');
$car2 = new Car('Ford', '300hp');

(который просто не будет работать), вы можете сделать:

$car = (new Car)
       ->setColor('blue')
       ->setMake('Ford')
       ->setDrive('FWD');

таким образом, вы можете выбрать именно те свойства, которые вы хотите установить. Во многом это похоже на передачу массива опций в ваш первоначальный вызов:

$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
?>

и, кажется, все довольны, но для меня это не сработало... если вы заставите его работать, его один вид перегрузки тоже...

Он принимает все аргументы и передает их в конструктор вторичной функции...

руководство 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);

Это не идеальное решение, но я сделал эту работу, разделив параметры на абсолютно обязательные параметры независимо от того, когда объект построен, и, как группа, дополнительные параметры, перечисленные в порядке важности.

это работает.

Я действительно не эксперт ООП, но как я понимаю перегрузка означает способность метода действовать по-разному в зависимости от параметров, которые он получает в качестве входных данных. Это очень возможно с PHP, вы просто не объявляете типы ввода, так как PHP не имеет сильного ввода, и вся перегрузка выполняется во время выполнения вместо времени компиляции.

вы можете использовать условные операторы в конструкторе, а затем выполнить вашу задачу. Например.

  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
//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");

?>

насколько я знаю, перегрузка конструктора в PHP не допускается, просто потому, что разработчики PHP не включили эту функциональность - это одна из многих жалоб на PHP.

Я слышал о трюках и обходных путях, но истинная перегрузка в смысле ООП отсутствует. Возможно, в будущих версиях он будет включен.

Я думаю, что мы также можем использовать конструктор с параметрами по умолчанию как потенциальная замена перегрузки конструктора в PHP.

тем не менее, это действительно печально, что истинная перегрузка конструктора не поддерживается в PHP.

<?php

    class myClass {

        public $param1 = 'a';
        public $param2 = 'b';

        public function __construct($param1 = NULL, $param2 = NULL) {

            if ($param1 == NULL && $param2 == NULL) {
//                $this->param1 = $param1;
//                $this->param2 = $param2;
            } elseif ($param1 == NULL && $param2 !== NULL) {
//                $this->param1 = $param1;
                $this->param2 = $param2;
            } elseif ($param1 !== NULL && $param2 == NULL) {
                $this->param1 = $param1;
//                $this->param2 = $param2;                
            } else {
                $this->param1 = $param1;
                $this->param2 = $param2;
            }

        }

    }

//    $myObject  = new myClass();
//    $myObject  = new myClass(NULL, 2);
    $myObject  = new myClass(1, '');
//    $myObject  = new myClass(1, 2);

    echo $myObject->param1;
    echo "<br />";
    echo $myObject->param2;

?>