Чому 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: Це все добре і добре, але питання ОП задає, чому PHP не застосовує "традиційні" перевантаження. Ваша відповідь не відповідає цьому.
Джоел Етертон

7
Це не перевантажує. Є ще одне визначення / оголошення функції. Це було б еквівалентно va_list / va_arg в C ++. Чи можете ви вирішити якісь ті самі проблеми? Так. Але це все ще не перевантажує.
Лука

13

Не повна підтримка "Традиційного перевантаження", лише часткова .

ВИЗНАЧЕННЯ : "Традиційна перевантаження" надає, при виклику методу, можливість мати кілька методів з одним іменем, але різні кількості та типи аргументів. Для декларування методу він надає можливість виразити окреме / ізольоване оголошення для кожної перевантаженої функції.

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


PHP ПІДТРИМКА :

  • ТАК, забезпечує можливість дзвінка кілька методів з однаковою назвою, але різними кількостями . Дивіться func_get_args та @rajukoyilandy відповідь, ми можемо використовувати f(x)і f(x,y).

  • ТАК, забезпечує можливість викликати кілька методів з однаковою назвою, але різних типів . Можливе внутрішнє використання геттипу в методі.

    • АЛЕ для довідок ... Лише змінні можуть передаватися за посиланням, ви не можете керувати перевантаженням для постійного / змінного виявлення.
  • НЕ надає можливість оголошувати кілька методів з однаковим іменем, але різними кількостями . Це тому, що ми можемо дзвонити 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.