web-dev-qa-db-ja.com

PHPが関数のオーバーロードをサポートしていないのはなぜですか?

プログラミング言語の主要な機能の1つは、引数を介して関数をオーバーロードする機能を備えているかどうかと思います。それはオブジェクト指向プログラミングの文脈において不可欠であると思います。

意図的に置き去りにして許可されていませんか?または、オーバーロードは良い習慣ではありませんか?

38
user1179459

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

2つの数値を加算する、または2つの文字列を連結する関数:

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
34
rajukoyilandy

Not a "Traditional Overloading"完全サポート部分のみ

A DEFINITION: "Traditional Overloading"は、callingメソッドの場合、同じ名前で引数の数とタイプが異なる複数のメソッドを持つ機能を提供します。メソッドdeclarationの場合、オーバーロードされた関数ごとに個別の/分離された宣言を表現するオプションが提供されます。

注:この定義の2番目の部分は通常、正しい宣言を選択するために、型チェックや アリティチェック を行うプログラミング言語 静的型付け に関連付けられています。 PHPは静的に型付けされた言語ではありません 動的です 、そして 弱い型付け を使用します。


PHPサポート

  • はい、call同じ名前で異なる数量の複数のメソッドを提供します。 func_get_args と@rajukoyilandyの回答を参照してください。f(x)f(x,y)を使用できます。

  • はい、call同じ名前で異なる型の複数のメソッドを提供します。メソッド内での gettype の内部使用。

    • しかし、参照については...参照によって渡すことができるのは変数のみであり、定数/変数検出のオーバーロードを管理することはできません。
  • NOTはdeclare同じ名前で複数のメソッド異なる数量のメソッドを提供します。これは、同じf宣言でf(x)f(x,y)を呼び出すことができるためです。

  • NOTはdeclare同じ名前で複数のメソッドを提供しますが、-異なる型です。これは、PHPコンパイラがf($integer,$string)f($string,$integer)と同じ関数として解釈する必要があるためです。

「非伝統的なオーバーロード」の説明については、 PHP5オーバーロードのドキュメント も参照してください。

15
Peter Krauss