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

Posted

技术标签:

【中文标题】什么是php中的函数重载和覆盖?【英文标题】:What is function overloading and overriding in php? 【发布时间】:2011-03-01 00:01:14 【问题描述】:

php 中,函数重载和函数覆盖是什么意思。他们两者有什么区别?无法弄清楚它们之间有什么区别。

【问题讨论】:

您可以在此链接中使用可重载类:***.com/questions/4697705/php-function-overloading/… 【参考方案1】:

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

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

【讨论】:

PHP 不支持重载。 是的,使用__call PHP 通过可选参数替代重载。 感谢可选参数的想法,这是一个非常有用的提示 __call() 在对象上下文中调用不可访问方法时触发 __callStatic() 在静态上下文中调用不可访问方法时触发 megic 方法。请按照此获取更详细的示例和 PHP 上下文中的重载说明:PHP Overloading【参考方案2】:

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

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 中规定的行为。

【讨论】:

PHP,AFAIK 不支持函数重载。另外,作为一个不相关的旁注,我不确定你为什么会有一个 Subtraction 类扩展 Addition 类。 :) @musicfreak:当地时间上午 12:40...想不出更好的例子。 PHP 尚不支持此功能,而且可能永远不会支持,因为 PHP 是弱类型语言,在这种情况下不会发生任何变化。 重载不仅仅是当你使用不同的参数集定义相同的函数名两次(或多次)时。通常,重载也是当您使用相同数量但类型不同的参数两次(或多次)定义相同的函数名称时。因为在 PHP 中没有变量类型声明(就像在 Java 中一样),所以这种概括并不重要。为了准确起见,我只是提到这一点,什么是重载。 @sbrbot:集合意味着数字和类型。【参考方案3】:

严格来说,没有区别,因为你不能这样做:)

函数覆盖可以通过像 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'

【讨论】:

PHP 5.x.x 不支持重载,这就是 PHP 不完全面向对象的原因。 不是PHP不支持重载,而是说不通。问题是由于 PHP 使用动态类型。事实上,Javascript 也不支持重载,它仍然是 OOP。 “PHP 不完全是 OOP”的说法只是因为有些人决定使用检查表来判断什么是 OOP。 @ringø 不,PHP 中的命名函数是不可变的。一旦在 PHP 中创建了命名函数,就无法修改其内部行为(覆盖)。除非你的意思是方法覆盖,这是别的东西。你应该在评论第一行之前阅读整个答案。 :) @Christian 好吧,当然是 PHP(和许多其他语言)overriding occurs in a class。所以,是的,我们谈论的是方法——即使它们中的每一个都以关键字function作为前缀。但实际上我应该先阅读整个答案......【参考方案4】:

重载示例

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

【讨论】:

不错的自定义实现,但应该由语言给出。 这不是方法,函数重载,而您为每个 puporse 使用不同的方法名称【参考方案5】:

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

如果你这样定义你的函数:

function f($p=0)

  if($p)
  
    //implement functionality #1 here
  
  else
  
    //implement functionality #2 here
  

当你像这样调用这个函数时:

f();

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

f(1);

您将获得另一个功能 (#2)。这就是重载的效果——不同的功能取决于函数的输入参数。

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

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

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

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

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

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

【讨论】:

【参考方案8】:

函数重载和覆盖虽然都包含相同的函数名,但还是有一些区别。在重载中,同名函数之间包含不同类型的参数或返回类型;例如: “函数添加(int a,int b)”&“函数添加(float a,float b); 这里 add() 函数被重载。 在覆盖参数和函数名相同的情况下,一般出现在继承或者traits中。我们必须按照一些策略来介绍,现在将执行什么函数。 因此,在重写时,程序员遵循一些策略来执行所需的功能,在重载时程序可以自动识别所需的功能......谢谢!

【讨论】:

【参考方案9】:

重载:在现实世界中,重载意味着给某人分配一些额外的东西。就像在现实世界中一样,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

【讨论】:

【参考方案10】:

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

【讨论】:

我不知道你从哪里得到过重载面向对象编程的要求的想法。 @drewish 因为参数多态性是 OOP 最重要的特性之一? @drewish 如果您将多态性视为 OOP 的主要停滞之一。然后表面上重载是为了编译。但是,方法重载是编译时的多态性,也称为静态多态性。

以上是关于什么是php中的函数重载和覆盖?的主要内容,如果未能解决你的问题,请参考以下文章

什么情况下是重载,什么情况下是重写,什么情况下是覆盖

java 重载和重写的区别

函数重载和覆盖(重写)的区别

重载覆盖

java 重载和重写的区别

什么是java方法重载