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

Par*_*rag 127 php overriding overloading

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

Jac*_*kin 189

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

在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"
?>
Run Code Online (Sandbox Code Playgroud)

  • PHP通过可选参数替换重载. (50认同)
  • 但是,PHP不支持重载. (31认同)
  • 是的,使用`__call`. (18认同)
  • 感谢可选参数的想法,这是一个非常有用的提示 (3认同)
  • 当在对象上下文中调用不可访问的方法时触发__call()__callStatic()在静态上下文中调用不可访问的方法时会触发megic方法.按照这个来获得更详细的PHP上下文重载示例和解释:[PHP重载](http://php.net/manual/en/language.oop5.overloading.php) (2认同)
  • @ b01确实它确实替代了; 用同样的方法可以用香蕉代替螺丝刀.它可以工作,也可能有效,但它有点不合适. (2认同)

And*_*ore 105

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

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

  function compute($first, $second, $third) {
    return $first+$second+$third;
  }
}
Run Code Online (Sandbox Code Playgroud)

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

class Addition {
  function compute($first, $second, $third = 0) {
    return $first+$second+$third;
  }
}
Run Code Online (Sandbox Code Playgroud)

扩展类并重写父类中存在的函数时会发生函数重写:

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

例如,compute覆盖中所述的行为Addition.

  • 除了PHP,AFAIK中不支持函数重载.另外,作为一个不相关的旁注,我不确定为什么你会有一个`Subtraction`类扩展`Addition`类.:) (9认同)
  • @musicfreak:当地时间上午12:40 ......想不出一个更好的例子. (6认同)
  • *这在PHP*中尚不支持,可能永远不会支持,因为PHP是弱类型语言,在这种情况下没有任何改变. (5认同)
  • 重载不仅在使用不同的参数集定义相同的函数名两次(或更多次)时.通常,当您使用相同数量的参数但使用不同类型定义相同的函数名两次(或更多次)时,也会发生重载.因为在PHP中没有变量类型声明(比如在Java中),所以这种泛化并不重要.我只是提到这个是为了确保重载是什么. (2认同)
  • @sbrbot:Set表示数字和类型. (2认同)

Chr*_*ian 22

严格来说,没有区别,因为你不能做任何一个:)

函数重写可以使用像APD这样的PHP扩展来完成,但它已被弃用,并且afaik最后一个版本无法使用.

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

$a=1;
$a='1';
$a=true;
$a=doSomething();
Run Code Online (Sandbox Code Playgroud)

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

int a=1;
String s="1";
bool a=true;
something a=doSomething();
Run Code Online (Sandbox Code Playgroud)

在最后一个示例中,您必须强制设置变量的类型(例如,我使用数据类型"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');
Run Code Online (Sandbox Code Playgroud)

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


最后,我想指出上述答复为何部分错误; 函数重载/覆盖不等于方法重载/覆盖.

在一个方法就像一个函数但特定于一个类的情况下,在这种情况下,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'
Run Code Online (Sandbox Code Playgroud)

  • 它不是PHP不支持重载,它是没有意义的.问题是由于PHP使用动态类型.事实上,Javascript也不支持重载,它仍然是OOP."PHP不完全是OOP"只存在,因为有些人决定使用检查表来判断是什么OOP. (29认同)
  • PHP 5.xx不支持重载这就是PHP不完全OOP的原因. (2认同)

小智 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);
Run Code Online (Sandbox Code Playgroud)


sbr*_*bot 5

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

如果你定义你的功能:

function f($p=0)
{
  if($p)
  {
    //implement functionality #1 here
  }
  else
  {
    //implement functionality #2 here
  }
}
Run Code Online (Sandbox Code Playgroud)

当您调用此函数时:

f();
Run Code Online (Sandbox Code Playgroud)

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

f(1);
Run Code Online (Sandbox Code Playgroud)

你会得到另一个功能(#2).这就是重载的影响 - 根据函数的输入参数不同的功能.

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