什么是PHP中的函数重载和重载?


Answers:


192

重载定义的函数具有相似的签名,但具有不同的参数。覆盖仅与派生类相关,派生类中的父类已定义了一个方法,而派生类希望覆盖该方法。

在PHP中,您只能使用magic方法重载方法__call

覆盖的示例:

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

31
但是,PHP不支持重载。
Sasha Chedygov

18
是的,使用可以__call
Jacob Relkin 2010年

50
PHP通过可选参数替代了重载。
b01

3
感谢可选参数的想法,这是一个非常有用的提示
法布里西奥PH

2
当在对象上下文中调用无法访问的方法时,将触发__call()。在静态上下文中调用无法访问的方法时,将触发__callStatic()逻辑方法。请按照以下步骤获取有关PHP上下文中的重载的更详细的示例和说明: PHP重载
Code Buster

107

当您使用不同的参数集两次(或多次)定义相同的函数名称时,就会发生函数重载。例如:

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

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

在上面的示例中,该函数compute重载了两个不同的参数签名。* PHP尚不支持此功能。一种替代方法是使用可选参数:

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

当您扩展一个类并重写父类中存在的函数时,就会发生函数重写:

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

例如,compute覆盖列出的行为Addition


9
除函数重载外,PHP,AFAIK不支持。另外,作为一个不相关的旁注,我不确定为什么要使用一个Subtraction类来扩展Addition该类。:)
Sasha Chedygov

6
@musicfreak:当地时间上午12:40 ...想不到一个更好的例子。
Andrew Moore 2010年

5
这在PHP中尚不支持,并且可能永远不会,因为PHP是弱类型的语言,在这种情况下没有任何改变。
Crozin

2
不仅当您使用不同的参数集两次(或更多次)定义相同的函数名称时,重载。通常,重载也是当您使用相同数量的参数但类型不同的参数两次(或多次)定义相同的函数名称时。由于在PHP中没有变量类型声明(如Java中的声明),因此这种概括并不重要。为了精确起见,我只是提到这是什么重载。
sbrbot

2
@sbrbot:Set表示数字和类型。
Andrew Moore

22

严格来说,没有区别,因为您不能做任何事:)

功能覆盖可以通过APD之类的PHP扩展来完成,但已过时,并且afaik的最新版本不可用。

PHP中的函数重载由于动态类型而无法完成,即,在PHP中,您不会将变量“定义”为特定类型。例:

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

每个变量都有不同的类型,但是您可以在执行之前知道其类型(请参阅第4个变量)。作为比较,其他语言使用:

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

在最后一个示例中,必须强制设置变量的类型(例如,我使用了数据类型“ something”)。


为什么在PHP中无法进行函数重载的另一个“问题”:PHP具有一个名为func_get_args()的函数,该函数返回当前参数的数组,现在考虑以下代码:

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

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

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

考虑到两个函数都接受任意数量的参数,编译器应选择哪个参数?


最后,我想指出为什么上述答复部分错误; 函数重载/重载不等于方法重载/重载。

在方法类似于函数但特定于类的情况下,在这种情况下,PHP确实允许在类中进行重写,但由于语言语义的原因,不允许重载。

总而言之,像Javascript这样的语言允许覆盖(但同样,没有重载),但是它们也可能显示覆盖用户功能和方法之间的区别:

/// 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'

2
PHP 5.xx不支持重载,这就是PHP不完全OOP的原因。
法拉利PHP

30
不是说PHP不支持重载,而是说它没有道理。该问题是由于PHP使用动态类型引起的。实际上,JavaScript也不支持重载,它仍然是OOP。“ PHP并非完全OOP”之所以存在,是因为有人决定使用检查表来判断什么是OOP。
克里斯蒂安

@ringø不,PHP中的命名函数是不可变的。用PHP创建命名函数后,就无法修改其内部行为(覆盖)。除非您是要重写方法,否则不然。.您可能应该在注释第一行之前阅读整个答案。:)
基督教徒

@Christian好吧,当然,在PHP(和许多其他语言)中,重写是在class中发生的。因此,是的,我们正在谈论方法-即使每个方法都以关键字function为前缀。但实际上我应该先阅读整个答案……
e2-e4

9

重载示例

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

不错的自定义实现,但是应该由语言给出。
4EACH

这不是方法,函数重载,而您为每个对象使用不同的方法名称
TomSawyer

5

尽管PHP并不完全支持重载范式,但可以使用默认参数(如之前提到的那样)实现相同(或非常相似)的效果。

如果您这样定义函数:

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

当您调用此函数时,如下所示:

f();

您将获得一种功能(#1),但是如果使用以下参数调用它:

f(1);

您将获得另一种功能(#2)。那就是重载的结果-不同的功能取决于函数的输入参数。

我知道,现在有人会问,如果他/她将此函数称为f(0),将会得到什么功能。


1

我想在这里指出,与其他编程语言相比,PHP重载具有完全不同的含义。很多人说过,PHP不支持重载,并且按传统的重载定义,是的,功能并没有明确可用。

但是,PHP中重载的正确定义完全不同。

在PHP中,重载是指使用诸如__set()和__get()之类的魔术方法动态创建属性和方法。与无法访问或未声明的方法或属性进行交互时,将调用这些重载方法。

这是PHP手册的链接:http : //www.php.net/manual/zh/language.oop5.overloading.php


1

当单个类中具有相同方法名称但参数数量不同的两个或多个方法时,将发生方法重载。PHP不支持方法重载。方法覆盖是指两个不同类中具有相同方法名称和相同参数数量的两个方法,即父类和子类。


0

尽管函数重载和覆盖都包含相同的函数名称,但它们之间还是有一些区别。在重载中,相同名称之间的函数包含不同类型的参数或返回类型;例如:“ function add(int a,int b)”&“ function add(float a,float b);这里的add()函数是重载的,在覆盖参数和函数名称的情况下,它们是相同的,通常在继承或特征中发现,我们必须遵循一些策略来引入,什么函数将立即执行,因此,在压倒一切的过程中,程序员遵循一些策略来执行所需的功能,在重载时,程序可以自动识别所需的功能...谢谢!


0

重载:在现实世界中,重载意味着向某人分配一些额外的东西。与现实世界一样,PHP中的重载意味着调用额外的函数。换句话说,您可以说它具有带有不同参数的更纤薄的函数。在PHP中,您可以对__get,__ set,__ call等魔术函数使用重载。

重载示例:

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

覆盖:在面向对象的编程中,覆盖是替换子类中的父方法。在覆盖中,您可以在子类中重新声明父类方法。因此,基本上,重写的目的是更改父类方法的行为。

覆盖示例:

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

-14

PHP 5.xx不支持重载,这就是PHP不完全OOP的原因。


18
我不知道您对超载面向对象编程的需求有何想法。
提请

6
@drewish,因为参数多态性是OOP的最重要特征之一?
达沃

1
@drewish,如果您将多态性视为OOP的主要停滞之一。然后表面上有重载用于编译。但是,方法重载是编译时多态,也称为静态多态。
Yasir Arefin'3
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.