Co to jest przeciążanie funkcji i nadpisywanie w PHP?

Odpowiedzi:

192

Przeciążanie to definiowanie funkcji, które mają podobne sygnatury, ale mają inne parametry. Zastępowanie ma zastosowanie tylko do klas pochodnych, w których klasa nadrzędna zdefiniowała metodę, a klasa pochodna chce przesłonić tę metodę.

W PHP można przeciążać metody tylko przy użyciu metody magicznej __call.

Przykład nadpisywania :

<?php

class Foo {
   function myFoo() {
      return "Foo";
   }
}

class Bar extends Foo {
   function myFoo() {
      return "Bar";
   }
}

$foo = new Foo;
$bar = new Bar;
echo($foo->myFoo()); //"Foo"
echo($bar->myFoo()); //"Bar"
?>
Jacob Relkin
źródło
31
PHP nie obsługuje jednak przeciążania.
Sasha Chedygov
18
Tak, używając __call.
Jacob Relkin
50
PHP zastępuje przeciążenie opcjonalnymi parametrami.
b01
3
Dzięki za pomysł parametrów opcjonalnych, to bardzo pomocna wskazówka
Rudolf Real
2
__call () jest wyzwalane, gdy niedostępne metody są wywoływane w kontekście obiektów. Metoda megic __callStatic () jest wyzwalana, gdy niedostępne metody są wywoływane w kontekście statycznym. Postępuj zgodnie z tym, aby uzyskać bardziej szczegółowy przykład i wyjaśnienie przeciążenia w kontekście PHP
Code Buster
108

Przeciążenie funkcji występuje, gdy definiujesz tę samą nazwę funkcji dwukrotnie (lub więcej) przy użyciu innego zestawu parametrów. Na przykład:

class Addition {
  function compute($first, $second) {
    return $first+$second;
  }

  function compute($first, $second, $third) {
    return $first+$second+$third;
  }
}

W powyższym przykładzie funkcja computejest przeciążona dwoma różnymi sygnaturami parametrów. * To nie jest jeszcze obsługiwane w PHP. Alternatywą jest użycie opcjonalnych argumentów:

class Addition {
  function compute($first, $second, $third = 0) {
    return $first+$second+$third;
  }
}

Przesłanianie funkcji występuje, gdy rozszerzasz klasę i przepisujesz funkcję, która istniała w klasie nadrzędnej:

class Substraction extends Addition {
  function compute($first, $second, $third = 0) {
    return $first-$second-$third;
  }
}

Na przykład computezastępuje zachowanie określone w Addition.

Andrew Moore
źródło
9
Poza tym, że przeciążanie funkcji nie jest obsługiwane w PHP, AFAIK. Poza tym, jako niezwiązana uwaga na marginesie, nie jestem pewien, dlaczego miałbyś mieć Subtractionklasę rozszerzającą Additionklasę. :)
Sasha Chedygov
6
@musicfreak: 00:40 czasu lokalnego ... Nie mogłem wymyślić lepszego przykładu.
Andrew Moore,
5
Nie jest to jeszcze obsługiwane w PHP i prawdopodobnie nigdy nie będzie, ponieważ PHP jest językiem słabo typowanym i nic się w tym przypadku nie zmieni.
Crozin
2
Przeciążanie występuje nie tylko wtedy, gdy definiujesz tę samą nazwę funkcji dwukrotnie (lub więcej razy) przy użyciu innego zestawu parametrów. Generalnie przeciążenie występuje również wtedy, gdy definiujesz tę samą nazwę funkcji dwukrotnie (lub więcej razy) przy użyciu tej samej liczby parametrów, ale różnych typów. Ponieważ w PHP nie ma deklaracji typu zmiennej (jak w Javie), to uogólnienie nie ma znaczenia. Wspominam o tym tylko ze względu na dokładność, czym jest przeciążenie.
sbrbot
2
@sbrbot: Set implikuje zarówno liczbę, jak i typy.
Andrew Moore
22

Ściśle mówiąc, nie ma różnicy, bo ty też nie możesz :)

Przesłanianie funkcji można było zrobić za pomocą rozszerzenia PHP, takiego jak APD, ale jest ono przestarzałe, a ostatnia wersja afaik była bezużyteczna.

Przeciążenie funkcji w PHP nie może być wykonane z powodu dynamicznego pisania, tj. W PHP nie można "definiować" zmiennych jako określonego typu. Przykład:

$a=1;
$a='1';
$a=true;
$a=doSomething();

Każda zmienna jest innego typu, ale możesz poznać typ przed wykonaniem (patrz czwarta). Dla porównania inne języki używają:

int a=1;
String s="1";
bool a=true;
something a=doSomething();

W ostatnim przykładzie musisz na siłę ustawić typ zmiennej (jako przykład użyłem typu danych „coś”).


Kolejny problem, dlaczego przeciążanie funkcji nie jest możliwe w PHP: PHP ma funkcję o nazwie func_get_args (), która zwraca tablicę bieżących argumentów. Rozważmy teraz następujący kod:

function hello($a){
  print_r(func_get_args());
}

function hello($a,$a){
  print_r(func_get_args());
}

hello('a');
hello('a','b');

Biorąc pod uwagę, że obie funkcje przyjmują dowolną liczbę argumentów, który z nich powinien wybrać kompilator?


Na koniec chciałbym wskazać, dlaczego powyższe odpowiedzi są częściowo błędne; Przeciążanie / przesłanianie funkcji NIE JEST równe przeciążaniu / przesłanianiu metody .

Gdy metoda jest podobna do funkcji, ale jest specyficzna dla klasy, w takim przypadku PHP zezwala na nadpisywanie w klasach, ale znowu bez przeciążania ze względu na semantykę języka.

Podsumowując, języki takie jak Javascript pozwalają na nadpisywanie (ale znowu bez przeciążania), jednak mogą również pokazywać różnicę między zastępowaniem funkcji użytkownika a metodą:

/// Function Overriding ///

function a(){
   alert('a');
}
a=function(){
   alert('b');
}

a(); // shows popup with 'b'


/// Method Overriding ///

var a={
  "a":function(){
    alert('a');
  }
}
a.a=function(){
   alert('b');
}

a.a(); // shows popup with 'b'
chrześcijanin
źródło
2
PHP 5.xx nie obsługuje przeciążania, dlatego PHP nie jest w pełni OOP.
PHP Ferrari
30
Nie chodzi o to, że PHP nie obsługuje przeciążania, ale o to, że nie ma to sensu. Problem jest spowodowany tym, że PHP używa typów dynamicznych. W rzeczywistości JavaScript również nie obsługuje przeciążania i nadal jest OOP. Błąd „PHP nie jest w pełni OOP” istnieje tylko dlatego, że niektórzy ludzie zdecydowali się użyć listy kontrolnej, aby ocenić, co jest OOP, a co nie.
Christian,
@ ringø Nie, nazwane funkcje w PHP są niezmienne. Po utworzeniu nazwanej funkcji w PHP nie ma możliwości zmodyfikowania jej wewnętrznego zachowania (nadpisania). Chyba, że ​​chodziło Ci o przesłanianie metody, co jest czymś innym .. Prawdopodobnie powinieneś przeczytać całą odpowiedź przed skomentowaniem pierwszej linii. :)
Christian
@Christian Cóż, oczywiście w PHP (i wielu innych językach) nadpisywanie występuje w klasie . Więc tak, mówimy o metodach - mimo że każda z nich jest poprzedzona słowem kluczowym function . Ale rzeczywiście powinienem był najpierw przeczytać całą odpowiedź ...
e2-e4
9

Przykład przeciążenia

class overload {
    public $name;
    public function __construct($agr) {
        $this->name = $agr;
    }
    public function __call($methodname, $agrument) {
         if($methodname == 'sum2') {

          if(count($agrument) == 2) {
              $this->sum($agrument[0], $agrument[1]);
          }
          if(count($agrument) == 3) {

              echo $this->sum1($agrument[0], $agrument[1], $agrument[2]);
          }
        }
    }
    public function sum($a, $b) {
        return $a + $b;
    }
    public function sum1($a,$b,$c) {

        return $a + $b + $c;
    }
}
$object = new overload('Sum');
echo $object->sum2(1,2,3);
Spacerować
źródło
Niezła implementacja niestandardowa, ale powinna być podana przez język.
KAŻDY
To nie jest metoda, przeciążenie funkcji, podczas gdy używasz innej nazwy metody dla każdego puporse
TomSawyer
5

Chociaż paradygmat przeciążania nie jest w pełni obsługiwany przez PHP, ten sam (lub bardzo podobny) efekt można osiągnąć za pomocą domyślnych parametrów (jak ktoś wspomniał wcześniej).

Jeśli zdefiniujesz swoją funkcję w ten sposób:

function f($p=0)
{
  if($p)
  {
    //implement functionality #1 here
  }
  else
  {
    //implement functionality #2 here
  }
}

Gdy wywołujesz tę funkcję, na przykład:

f();

otrzymasz jedną funkcjonalność (nr 1), ale jeśli wywołasz ją z parametrem takim jak:

f(1);

dostaniesz inną funkcjonalność (# 2). To efekt przeciążenia - różne funkcje w zależności od parametrów wejściowych funkcji.

Wiem, ktoś zapyta teraz, jaką funkcjonalność otrzyma, jeśli nazwie tę funkcję jako f (0).

sbrbot
źródło
2

Przeciążenie metod występuje, gdy dwie lub więcej metod ma tę samą nazwę metody, ale inną liczbę parametrów w jednej klasie. PHP nie obsługuje przeciążania metod. Przesłanianie metody oznacza dwie metody o tej samej nazwie metody i tej samej liczbie parametrów w dwóch różnych klasach, co oznacza klasę nadrzędną i podrzędną.

Shriyash Deshmukh
źródło
1

Chciałbym tu zaznaczyć, że przeciążanie w PHP ma zupełnie inne znaczenie w porównaniu z innymi językami programowania. Wiele osób powiedziało, że przeciążanie nie jest obsługiwane w PHP i zgodnie z konwencjonalną definicją przeciążania, tak, ta funkcjonalność nie jest jawnie dostępna.

Jednak prawidłowa definicja przeciążenia w PHP jest zupełnie inna.

W PHP przeciążanie odnosi się do dynamicznego tworzenia właściwości i metod przy użyciu magicznych metod, takich jak __set () i __get (). Te metody przeciążania są wywoływane podczas interakcji z metodami lub właściwościami, które nie są dostępne lub nie są zadeklarowane.

Oto link z podręcznika PHP: http://www.php.net/manual/en/language.oop5.overloading.php

Ram Iyer
źródło
0

Istnieją pewne różnice między przeciążaniem i zastępowaniem funkcji, chociaż obie zawierają tę samą nazwę funkcji. W przypadku przeciążenia funkcje o tej samej nazwie zawierają różne typy argumentów lub zwracanych typów; Na przykład: "function add (int a, int b)" & " function add (float a, float b); Tutaj funkcja add () jest przeciążona. W przypadku przesłonięcia zarówno argument, jak i nazwa funkcji są takie same. Zwykle występuje w dziedziczeniu lub w cechach. Musimy zastosować pewną taktykę, aby wprowadzić , jaka funkcja będzie teraz wykonywana. Więc podczas nadpisywania programista stosuje pewną taktykę, aby wykonać żądaną funkcję, w której w przeciążeniu program może automatycznie zidentyfikować żądaną funkcję ... Dzięki!

Mashuq Tanmoy
źródło
0

Przeciążanie: W prawdziwym świecie przeciążenie oznacza przypisanie komuś dodatkowych rzeczy. Jak w prawdziwym świecie Przeciążanie w PHP oznacza wywoływanie dodatkowych funkcji. Inaczej mówiąc, możesz powiedzieć, że ma szczuplejszą funkcję z innym parametrem. W PHP możesz użyć przeciążenia za pomocą funkcji magicznych, np. __Get, __set, __call itp.

Przykład przeciążenia:

class Shape {
   const Pi = 3.142 ;  // constant value
  function __call($functionname, $argument){
    if($functionname == 'area')
    switch(count($argument)){
        case 0 : return 0 ;
        case 1 : return self::Pi * $argument[0] ; // 3.14 * 5
        case 2 : return $argument[0] * $argument[1];  // 5 * 10
    }

  }

 }
 $circle = new Shape();`enter code here`
 echo "Area of circle:".$circle->area()."</br>"; // display the area of circle Output 0
 echo "Area of circle:".$circle->area(5)."</br>"; // display the area of circle
 $rect = new Shape();
 echo "Area of rectangle:".$rect->area(5,10); // display area of rectangle

Przesłanianie: W programowaniu zorientowanym obiektowo nadpisywanie polega na zastąpieniu metody nadrzędnej w klasie potomnej. W przypadku przesłonięcia można ponownie zadeklarować metodę klasy nadrzędnej w klasie potomnej. Zatem zasadniczo celem przesłonięcia jest zmiana zachowania metody klasy nadrzędnej.

Przykład nadpisywania:

class parent_class
{

  public function text()    //text() is a parent class method
  {
    echo "Hello!! everyone I am parent class text method"."</br>";
  }
  public function test()   
  {
    echo "Hello!! I am second method of parent class"."</br>";
  }

}

class child extends parent_class
{
  public function text()     // Text() parent class method which is override by child 
  class
  {
    echo "Hello!! Everyone i am child class";
  }

 }

 $obj= new parent_class();
 $obj->text();            // display the parent class method echo
 $obj= new parent_class();
 $obj->test();
 $obj= new child();
 $obj->text(); // display the child class method echo
user3040433
źródło
-14

PHP 5.xx nie obsługuje przeciążania, dlatego PHP nie jest w pełni OOP.

PHP Ferrari
źródło
18
Nie wiem, skąd wziął się pomysł, aby przeciążać wymaganie programowania zorientowanego obiektowo.
drewish
6
@drewish, ponieważ polimorfizm parametryczny jest jedną z najważniejszych cech OOP?
Davor
1
@drewish, jeśli uznasz polimorfizm za jedną z głównych stagnacji OOP. Następnie kompilacja jest rzekomo przeciążana. Jednak przeciążanie metod jest polimorfizmem czasu kompilacji, znanym również jako polimorfizm statyczny.
Yasir Arefin