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

时间:2010-06-08 04:30:47

标签: php overloading function-overriding

在PHP中,你的意思是函数重载和函数重写。它们两者有什么区别?无法弄清楚它们之间有什么区别。

10 个答案:

答案 0 :(得分:186)

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

在PHP中,您只能使用魔术方法__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"
?>

答案 1 :(得分:103)

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

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中列出的行为。

答案 2 :(得分: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'

答案 3 :(得分: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);

答案 4 :(得分:5)

尽管PHP不完全支持重载范例,但使用默认参数可以实现相同(或非常相似)的效果(如前所述)。

如果你定义你的功能:

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

当您调用此函数时:

f();

你将获得一个功能(#1),但如果你用以下参数调用它:

f(1);

你将获得另一项功能(#2)。这就是重载的影响 - 根据函数的输入参数不同的功能。

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

答案 5 :(得分:1)

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

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

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

以下是PHP手册中的链接:http://www.php.net/manual/en/language.oop5.overloading.php

答案 6 :(得分:0)

功能重载和功能之间存在一些差异。重写虽然两者都包含相同的函数名。在重载时,同名函数之间包含不同类型的参数或返回类型;如:   &#34;函数add(int a,int b)&#34; &安培; &#34;函数add(float a,float b); 这里add()函数被重载。 在覆盖的情况下,参数和函数名称都是相同的。它通常在继承或特征中找到。我们必须遵循一些策略来介绍,现在将执行什么功能。 所以在重写程序员时遵循一些策略来执行所需的功能,在重载时程序可以自动识别所需的功能......谢谢!

答案 7 :(得分: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

答案 8 :(得分:0)

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

答案 9 :(得分:-14)

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