什么是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中的函数重载和覆盖?的主要内容,如果未能解决你的问题,请参考以下文章