Почему PHP не поддерживает перегрузку функций?


37

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

Это намеренно оставлено позади и не позволено? Или перегрузка не очень хорошая практика?


27
Перегрузка функций на самом деле не особенность программирования ОО. Функция Подкласса наиважнейшая для целей полиморфизма, как правило , считается необходимой особенностью OO - но не перегрузками функций на основе аргументов. В Python также нет перегрузки функций на основе аргументов. В любом случае, перегрузка функций, вероятно, более практична в статически типизированных языках, где привязка функций происходит во время компиляции и основана на типе каждого параметра функции.
Чарльз Сальвия

2
@CharlesSalvia Это был бы хороший ответ.
kiamlaluno

1
Что он сказал. Кроме того, перегрузка функции переоценена. Вам не нужно использовать одно и то же имя функции для разных функций; просто дайте своим функциям имена, которые похожи, но не идентичны. С другой стороны, перегрузка оператора ...
Мистер Листер

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

Ответы:


33

Кто вам сказал, что PHP не поддерживает перегрузку функций? !!!

На самом деле PHP поддерживает перегрузку функций, но по-другому. Функции перегрузки PHP отличаются от функций Java:

Интерпретация PHP «перегрузки» отличается от большинства объектно-ориентированных языков. Традиционно перегрузка дает возможность иметь несколько методов с одинаковыми именами, но разными количествами и типами аргументов.

Оформить заказ следующие блоки кода.

Функция для нахождения суммы из n чисел:

function findSum() {
    $sum = 0;
    foreach (func_get_args() as $arg) {
        $sum += $arg;
    }
    return $sum;
}

echo findSum(1, 2), '<br />'; //outputs 3
echo findSum(10, 2, 100), '<br />'; //outputs 112
echo findSum(10, 22, 0.5, 0.75, 12.50), '<br />'; //outputs 45.75

Функция для добавления двух чисел или объединения двух строк:

function add() {
    //cross check for exactly two parameters passed
    //while calling this function
    if (func_num_args() != 2) {
        trigger_error('Expecting two arguments', E_USER_ERROR);
    }

    //getting two arguments
    $args = func_get_args();
    $arg1 = $args[0];
    $arg2 = $args[1];

    //check whether they are integers
    if (is_int($arg1) && is_int($arg2)) {
        //return sum of two numbers
        return $arg1 + $arg2;
    }

    //check whether they are strings
    if (is_string($arg1) && is_string($arg2)) {
        //return concatenated string
        return $arg1 . ' ' . $arg2;
    }

    trigger_error('Incorrect parameters passed', E_USER_ERROR);
}

echo add(10, 15), '<br />'; //outputs 25
echo add("Hello", "World"), '<br />'; //outputs Hello World

Объектно-ориентированный подход, включая перегрузку метода:

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

Ссылка: http://php.net/manual/en/language.oop5.overloading.php

В PHP перегрузка означает, что вы можете добавлять члены объекта во время выполнения, реализуя некоторые магические методы, такие как __set, __getи __callт. Д.

class Foo {

    public function __call($method, $args) {

        if ($method === 'findSum') {
            echo 'Sum is calculated to ' . $this->_getSum($args);
        } else {
            echo "Called method $method";
        }
    }

    private function _getSum($args) {
        $sum = 0;
        foreach ($args as $arg) {
            $sum += $arg;
        }
        return $sum;
    }

}

$foo = new Foo;
$foo->bar1(); // Called method bar1
$foo->bar2(); // Called method bar2
$foo->findSum(10, 50, 30); //Sum is calculated to 90
$foo->findSum(10.75, 101); //Sum is calculated to 111.75

29
Второй момент о том, что PHP называет «перегрузкой», не очень похож. Это просто PHP, использующий хорошо известное имя для чего-то совершенно другого, учитывая, что это PHP, хотя это не так удивительно.
phant0m

10
Это не перегрузка функций. Чтобы действительно перегрузить функцию, напишите php-эквивалент findSum(10, "steve", { 86, "2012-09-20" });. Истинная перегрузка позволила бы новые параметры различных типов.
Джоэл Этертон

3
@JoelEtherton - интерпретация PHP «перегрузки» отличается от большинства объектно-ориентированных языков. Традиционно перегрузка дает возможность иметь несколько методов с одинаковыми именами, но разными количествами и типами аргументов. ref: http://php.net/manual/en/language.oop5.overloading.php Перегрузка в PHP предоставляет средства для динамического «создания» свойств и методов. Эти динамические объекты обрабатываются с помощью магических методов, которые можно установить в классе для различных типов действий.
rajukoyilandy

7
@rajukoyilandy: Это все хорошо, но вопрос OP спрашивает, почему PHP не реализует «традиционную» перегрузку. Ваш ответ не относится к этому.
Джоэл Этертон

7
Это не перегрузка. Существует еще только одно определение / объявление функции. Это будет эквивалентно va_list / va_arg в C ++. Можете ли вы решить некоторые из тех же проблем? Да. Но это все еще не перегружает.
Лука,

13

Не полная поддержка "Традиционной перегрузки", только частичная .

ОПРЕДЕЛЕНИЕ : «Традиционная перегрузка» предоставляет при вызове метода возможность иметь несколько методов с одинаковым именем, но разными количествами и типами аргументов. Для объявления метода он предоставляет возможность выразить отдельное / изолированное объявление для каждой перегруженной функции.

Примечание: вторая часть этого определения обычно связана со статически типизированными языками программирования, которые выполняют проверку типов и / или проверку на соответствие , чтобы выбрать правильное объявление. PHP не является статически типизированным языком, он динамический и использует слабую типизацию .


PHP ПОДДЕРЖКА :

  • ДА, предоставляет возможность вызывать несколько методов с одинаковыми именами, но разными количествами . Смотрите func_get_args и @rajukoyilandy ответ, мы можем использовать f(x)и f(x,y).

  • ДА, предоставляет возможность вызывать несколько методов с одинаковыми именами, но разными типами . Само по себе внутреннее использование gettype в методе.

    • НО для ссылок ... Только переменные могут быть переданы по ссылке, вы не можете управлять перегрузкой для обнаружения констант / переменных.
  • НЕ предоставляет возможность объявлять несколько методов с одним и тем же именем, но разными количествами . Это потому что мы можем звонить f(x)и f(x,y)с одной и той же fдекларацией.

  • НЕ предоставляет возможность объявлять несколько методов с одинаковыми именами, но разными типами . Это потому, что компилятор PHP должен интерпретировать f($integer,$string) как ту же функцию, что и f($string,$integer).

См. Также документацию по перегрузке PHP5 для объяснения «нетрадиционной перегрузки».

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.