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


37

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

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


27
関数のオーバーロードは、実際にはオブジェクト指向プログラミングの機能ではありません。サブクラスの機能の上に乗り多型の目的のためには、通常、OOのに必要な機能と考えられている-しかし、引数に基づいて過負荷に機能しません。Pythonにも引数ベースの関数のオーバーロードはありません。とにかく、関数のオーバーロードはおそらく、コンパイル時に関数のバインドが発生し、各関数パラメーターの型に基づいている静的型付け言語ではより実用的です。
チャールズサルビア

2
@CharlesSalviaそれは良い答えでしょう。
キアムルノ

1
彼が言った事。また、関数のオーバーロードは過大評価されています。異なる関数に同じ関数名を使用する必要はありません。似ているが同一ではない関数名を付けるだけです。一方、オペレーターのオーバーロード...
ミスターリスター

特定の質問に対する答えではありませんが、PHPでオーバーロードを使用する方法をよりよく理解できるように、このリンクを投稿します。それが役に立てば幸い
DiegoDD

回答:


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

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

29
PHPが「オーバーロード」と呼ぶものについての2番目のビットは、それほど似ていません。それは、PHPであることを考慮して、ほとんど異なるものに十分に確立された名前を使用しているPHPにすぎません。
phant0m

10
それは関数のオーバーロードではありません。関数を本当にオーバーロードするには、に相当するphpを記述しfindSum(10, "steve", { 86, "2012-09-20" });ます。真のオーバーロードは、異なるタイプの新しいパラメーターを許可します。
ジョエルイーサートン

3
@JoelEtherton-PHPの「オーバーロード」の解釈は、ほとんどのオブジェクト指向言語とは異なります。オーバーロードは、従来、同じ名前で複数のメソッドを持つことができますが、引数の量とタイプが異なります。ref:http : //php.net/manual/en/language.oop5.overloading.php PHPのオーバーロードは、プロパティとメソッドを動的に「作成」する手段を提供します。これらの動的なエンティティは、さまざまなアクションタイプのクラスで確立できるマジックメソッドを介して処理されます。
rajukoyilandy

7
@rajukoyilandy:それはすべてうまくいっていますが、OPの質問は、なぜPHPが「伝統的な」オーバーロードを実装しないのかという質問です。あなたの答えはそれを解決しません。
ジョエルイーサートン

7
これは過負荷ではありません。関数の定義/宣言はまだ1つしかありません。これは、C ++のva_list / va_argと同等です。同じ問題のいくつかを解決できますか?はい。しかし、それはまだ過負荷ではありません。
ルーク

13

ない「伝統のオーバーロード」のフルサポート、部分的にしか

定義:「従来のオーバーロード」は、メソッドを呼び出すときに、同じ名前で引数の量とタイプが異なる複数のメソッドを持つ機能を提供します。メソッド宣言の場合、オーバーロードされた各関数に対して個別の/分離された宣言を表すオプションを提供します。

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


PHPのサポート

  • はい、次の機能を提供します 同じ名前で異なる数量の複数のメソッド呼び出す。参照func_get_argsと@rajukoyilandy答えを、私たちは使用することができるf(x)f(x,y)

  • はい、次の機能を提供します 同じ名前で異なるタイプの複数のメソッド呼び出すます。メソッドでのgettypeの内部使用 。

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

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

こちらもご覧ください 「非伝統的なオーバーロード」の説明については、PHP5オーバーロードのドキュメント

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.