为什么PHP不支持函数重载?


37

我想知道编程语言的主要功能之一是否能够通过参数重载函数。我认为这是面向对象编程必不可少的内容。

它是故意遗留下来并且不允许的吗?还是超载不是一个好习惯?


27
函数重载并不是OO编程的真正功能。子类函数压倒一切的多态性的目的通常被认为是OO的必要功能-但不是功能根据参数重载。Python也没有基于参数的函数重载。无论如何,函数重载在静态类型的语言中可能更实用,在静态类型的语言中,函数绑定是在编译时发生的,并且基于每个函数参数的类型。
Charles Salvia 2012年

2
@CharlesSalvia那将是一个很好的答案。
kiamlaluno

1
他说什么。同样,函数重载也被高估了。您不必为不同的功能使用相同的功能名称;只要给您的函数名称相似但不相同即可。另一方面,操作员超载...
Lister先生,

尽管不是特定问题的答案,但我将发布此链接,这使我更好地了解了如何在PHP中使用重载。希望对您有帮助
DiegoDD

Answers:


33

谁告诉你PHP不支持函数重载?

实际上,PHP确实支持函数重载,但是以不同的方式。PHP的重载功能与Java的重载功能不同:

PHP对“重载”的解释与大多数面向对象的语言不同。传统上,重载提供了具有名称相同但参数数量和类型不同的多个方法的能力。

签出以下代码块。

查找n个数字之和的函数:

function findSum() {
    $sum = 0;
    foreach (func_get_args() as $arg) {
        $sum += $arg;
    }
    return $sum;
}

echo findSum(1, 2), '<br />'; //outputs 3
echo findSum(10, 2, 100), '<br />'; //outputs 112
echo findSum(10, 22, 0.5, 0.75, 12.50), '<br />'; //outputs 45.75

添加两个数字或连接两个字符串的函数:

function add() {
    //cross check for exactly two parameters passed
    //while calling this function
    if (func_num_args() != 2) {
        trigger_error('Expecting two arguments', E_USER_ERROR);
    }

    //getting two arguments
    $args = func_get_args();
    $arg1 = $args[0];
    $arg2 = $args[1];

    //check whether they are integers
    if (is_int($arg1) && is_int($arg2)) {
        //return sum of two numbers
        return $arg1 + $arg2;
    }

    //check whether they are strings
    if (is_string($arg1) && is_string($arg2)) {
        //return concatenated string
        return $arg1 . ' ' . $arg2;
    }

    trigger_error('Incorrect parameters passed', E_USER_ERROR);
}

echo add(10, 15), '<br />'; //outputs 25
echo add("Hello", "World"), '<br />'; //outputs Hello World

面向对象的方法,包括方法重载:

PHP中的重载提供了动态“创建”属性和方法的方法。这些动态实体通过魔术方法处理,可以在类中为各种动作类型建立。

参考:http : //php.net/manual/en/language.oop5.overloading.php

在PHP中,超载意味着你可以在运行时添加对象的成员,通过实施一些神奇的方法,比如__set__get__call等。

class Foo {

    public function __call($method, $args) {

        if ($method === 'findSum') {
            echo 'Sum is calculated to ' . $this->_getSum($args);
        } else {
            echo "Called method $method";
        }
    }

    private function _getSum($args) {
        $sum = 0;
        foreach ($args as $arg) {
            $sum += $arg;
        }
        return $sum;
    }

}

$foo = new Foo;
$foo->bar1(); // Called method bar1
$foo->bar2(); // Called method bar2
$foo->findSum(10, 50, 30); //Sum is calculated to 90
$foo->findSum(10.75, 101); //Sum is calculated to 111.75

29
PHP所谓的“超载”的第二点并不完全相同。考虑到它是PHP,只是PHP使用一个公认的名称来表示大多数不同的名称,但这并不奇怪。
phant0m 2012年

10
那不是函数重载。为了真正重载函数,现在编写等效于的php findSum(10, "steve", { 86, "2012-09-20" });。真正的重载将允许使用不同类型的新参数。
乔尔·埃瑟顿

3
@JoelEtherton-PHP对“重载”的解释与大多数面向对象的语言不同。传统上,重载提供了具有名称相同但参数数量和类型不同的多个方法的能力。参考:http : //php.net/manual/zh/language.oop5.overloading.php PHP中的重载提供了动态“创建”属性和方法的方法。这些动态实体通过魔术方法处理,可以在类中为各种动作类型建立。
rajukoyilandy 2012年

7
@rajukoyilandy:很好,但是OP的问题问为什么PHP不实现“传统”重载。您的答案无法解决。
乔尔·埃瑟顿

7
这不是超载。函数只有一个定义/声明。这等效于C ++中的va_list / va_arg。您能解决一些相同的问题吗?是。但是它仍然没有过载。
路加福音

13

没有 “传统超载”的完全支持,只有部分支持。

定义:“传统重载”在调用方法时提供了具有名称相同但参数数量和类型不同的多个方法的能力。对于方法声明,它提供了为每个重载函数表达单独/隔离的声明的选项。

注意:此定义的第二部分通常与静态类型的编程语言相关联,这些语言进行类型检查和/或Arity检查,以选择正确的声明。PHP不是静态类型的语言,它是动态的,并且使用弱类型


PHP支持

  • 是的,可以调用具有相同名称但数量不同的多个方法。参见func_get_args和@rajukoyilandy答案,我们可以使用f(x)f(x,y)

  • 是的,可以调用具有相同名称但不同类型的多个方法。在内部使用 gettype方法。

    • 但用于引用...只能通过引用传递变量,不能管理常量/变量检测的重载。
  • NOT提供了声明具有相同名称但数量不同的多个方法的能力。这是因为我们可以使用f(x)f(x,y)进行相同的f声明。

  • NOT提供了声明具有相同名称但不同类型的多个方法的能力。这是因为PHP编译器必须将解释f($integer,$string)f($string,$integer)

另请参见PHP5重载文档,以获取“非传统重载”的说明。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.