【发布时间】:2011-03-01 00:01:14
【问题描述】:
在 PHP 中,函数重载和函数覆盖是什么意思。他们两者有什么区别?无法弄清楚它们之间有什么区别。
【问题讨论】:
标签: php overloading overriding
在 PHP 中,函数重载和函数覆盖是什么意思。他们两者有什么区别?无法弄清楚它们之间有什么区别。
【问题讨论】:
标签: php overloading overriding
重载是定义具有相似签名但具有不同参数的函数。 覆盖仅与派生类相关,其中父类定义了一个方法,而派生类希望覆盖该方法。
在 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"
?>
【讨论】:
__call。
当您使用不同的参数集定义相同的函数名称两次(或更多)时,就会发生函数重载。例如:
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 中规定的行为。
【讨论】:
Subtraction 类扩展 Addition 类。 :)
严格来说,没有区别,因为你不能这样做:)
函数覆盖可以通过像 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'
【讨论】:
重载示例
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);
【讨论】:
尽管 PHP 不完全支持重载范例,但使用默认参数(如前所述)可以实现相同(或非常相似)的效果。
如果你这样定义你的函数:
function f($p=0)
{
if($p)
{
//implement functionality #1 here
}
else
{
//implement functionality #2 here
}
}
当你像这样调用这个函数时:
f();
您将获得一项功能 (#1),但如果您使用以下参数调用它:
f(1);
您将获得另一个功能 (#2)。这就是重载的效果——不同的功能取决于函数的输入参数。
我知道,现在有人会问如果他/她将此函数称为 f(0),将获得什么功能。
【讨论】:
当一个类中有两个或多个方法名称相同但参数数量不同的方法时,会发生方法重载。 PHP 不支持方法重载。 方法覆盖是指两个不同类中方法名相同,参数个数相同的两个方法,即父类和子类。
【讨论】:
我想在这里指出,与其他编程语言相比,PHP 中的重载具有完全不同的含义。很多人都说 PHP 不支持重载,并且按照传统的重载定义,是的,功能不是明确可用的。
但是,PHP 中重载的正确定义是完全不同的。
在 PHP 中,重载是指使用 __set() 和 __get() 等魔术方法动态创建属性和方法。当与不可访问或未声明的方法或属性交互时,会调用这些重载方法。
这是 PHP 手册的链接:http://www.php.net/manual/en/language.oop5.overloading.php
【讨论】:
函数重载和覆盖虽然都包含相同的函数名,但还是有一些区别。在重载中,同名函数之间包含不同类型的参数或返回类型;例如: “函数添加(int a,int b)”&“函数添加(float a,float b); 这里 add() 函数被重载。 在覆盖参数和函数名相同的情况下,一般出现在继承或者traits中。我们必须按照一些策略来介绍,现在将执行什么函数。 因此,在重写时,程序员遵循一些策略来执行所需的功能,在重载时程序可以自动识别所需的功能......谢谢!
【讨论】:
重载:在现实世界中,重载意味着给某人分配一些额外的东西。就像在现实世界中一样,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
【讨论】:
PHP 5.x.x 不支持重载,这就是 PHP 不完全 OOP 的原因。
【讨论】: