Dlaczego PHP nie obsługuje przeciążania funkcji?

37

Zastanawiam się, czy jedną z kluczowych cech języka programowania jest możliwość przeciążania funkcji argumentami. Myślę, że jest to niezbędne w kontekście programowania obiektowego.

Czy jest to celowo pozostawione w tyle i niedozwolone? Czy przeciążanie nie jest dobrą praktyką?

użytkownik1179459
źródło
27
Przeciążenie funkcji nie jest tak naprawdę funkcją programowania OO. Nadrzędna funkcja podklasy dla celów polimorfizmu jest zwykle uważana za niezbędną cechę OO - ale nie przeciążenie funkcji na podstawie argumentów. Python nie ma też przeciążenia funkcji opartej na argumentach. W każdym razie przeciążenie funkcji jest prawdopodobnie bardziej praktyczne w językach o typie statycznym, w których wiązanie funkcji odbywa się w czasie kompilacji i jest oparte na typie każdego parametru funkcji.
Charles Salvia,
2
@CharlesSalvia To byłaby dobra odpowiedź.
kiamlaluno
1
Co on powiedział. Przeciążenie funkcji jest również przereklamowane. Nie musisz używać tej samej nazwy funkcji dla różnych funkcji; po prostu podaj nazwy funkcji, które są podobne, ale nie identyczne. Z drugiej strony przeciążenie operatora ...
Pan Lister
Chociaż nie jest to odpowiedź na konkretne pytanie, opublikuję ten link, który pozwolił mi lepiej zrozumieć JAK używać przeciążania w PHP. mam nadzieję, że to pomoże
DiegoDD,

Odpowiedzi:

33

Kto powiedział ci, że PHP nie obsługuje przeciążania funkcji? !!!

W rzeczywistości PHP obsługuje przeciążanie funkcji, ale w inny sposób. Funkcje przeciążania PHP różnią się od Java:

Interpretacja „przeciążenia” w PHP różni się od większości języków obiektowych. Przeciążenie tradycyjnie zapewnia możliwość posiadania wielu metod o tej samej nazwie, ale różnych ilościach i typach argumentów.

Sprawdź następujące bloki kodu.

Funkcja znajdująca sumę n liczb:

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

Funkcja dodawania dwóch liczb lub łączenia dwóch ciągów:

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

Podejście obiektowe, w tym przeciążenie metod:

Przeładowanie w PHP zapewnia dynamiczne „tworzenie” właściwości i metod. Te dynamiczne byty przetwarzane są za pomocą magicznych metod, które można ustanowić w klasie dla różnych rodzajów akcji.

Patrz: http://php.net/manual/en/language.oop5.overloading.php

W PHP, przeciążenia środki można dodać członków obiektu w czasie wykonywania, poprzez wdrożenie niektórych magicznych metod, takich jak __set, __get, __callitd.

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
rajukoyilandy
źródło
29
Druga część tego, co PHP nazywa „przeładowaniem”, nie jest aż tak podobna. To po prostu PHP, które używa dobrze ugruntowanej nazwy dla czegoś zasadniczo innego, biorąc pod uwagę, że to PHP, nie jest to jednak takie zaskakujące.
phant0m
10
To nie jest przeciążenie funkcji. Aby naprawdę przeciążyć funkcję, napisz teraz odpowiednik php findSum(10, "steve", { 86, "2012-09-20" });. Prawdziwe przeciążenie pozwoliłoby na nowe parametry różnych typów.
Joel Etherton,
3
@JeelEtherton - interpretacja PHP „przeciążenia” różni się od większości języków obiektowych. Przeciążenie tradycyjnie zapewnia możliwość posiadania wielu metod o tej samej nazwie, ale różnych ilościach i typach argumentów. ref: http://php.net/manual/en/language.oop5.overloading.php Przeciążenie w PHP zapewnia środki do dynamicznego „tworzenia” właściwości i metod. Te dynamiczne byty przetwarzane są za pomocą magicznych metod, które można ustanowić w klasie dla różnych rodzajów akcji.
rajukoyilandy,
7
@rajukoyilandy: Wszystko dobrze i dobrze, ale pytanie OP pyta, dlaczego PHP nie implementuje „tradycyjnego” przeciążenia. Twoja odpowiedź nie rozwiązuje tego problemu.
Joel Etherton,
7
To nie jest przeciążanie. Wciąż istnieje tylko jedna definicja / deklaracja funkcji. Byłoby to równoważne va_list / va_arg w C ++. Czy potrafisz rozwiązać niektóre z tych samych problemów? Tak. Ale to wciąż nie jest przeciążające.
Luke
13

Nie pełne wsparcie „tradycyjnego przeciążenia”, tylko częściowe .

DEFINICJA : „Tradycyjne przeładowanie” zapewnia, podczas wywoływania metody, możliwość posiadania wielu metod o tej samej nazwie, ale różnych ilościach i typach argumentów. W przypadku deklaracji metody udostępnia opcję wyrażenia oddzielnej / izolowanej deklaracji dla każdej przeciążonej funkcji.

Uwaga: druga część tej definicji jest zwykle kojarzona ze statycznymi typami języków programowania, które wykonują sprawdzanie typów i / lub sprawdzanie poprawności , aby wybrać poprawną deklarację. PHP nie jest językiem o typie statycznym, jest dynamiczny i używa słabego pisania .


WSPARCIE PHP :

  • TAK, umożliwia wywołanie wielu metod o tej samej nazwie, ale różnych ilościach . Zobacz func_get_args i odpowiedź @rajukoyilandy, możemy użyć f(x)i f(x,y).

  • TAK, umożliwia wywołanie wielu metod o tej samej nazwie, ale różnych typach . Zobacz wewnętrzne użycie gettype w metodzie.

    • ALE dla referencji ... Tylko zmienne mogą być przekazywane przez referencję, nie możesz zarządzać przeciążeniem dla wykrywania stałej / zmiennej.
  • NIE zapewnia możliwości deklarowania wielu metod o tej samej nazwie, ale różnych ilościach . Jest tak, ponieważ możemy zadzwonić f(x)i f(x,y)z tą samą fdeklaracją.

  • NIE zapewnia możliwości deklarowania wielu metod o tej samej nazwie, ale różnych typach . Wynika to z faktu, że kompilator PHP musi interpretować f($integer,$string) tę samą funkcję, co f($string,$integer).

Zobacz także dokumentację przeciążania PHP5, aby uzyskać wyjaśnienia dotyczące „nietradycyjnego przeciążania”.

Peter Krauss
źródło