PHP가 함수 오버로딩을 지원하지 않는 이유는 무엇입니까?


37

프로그래밍 언어의 주요 기능 중 하나가 인수를 통해 함수를 오버로드하는 기능인지 궁금합니다. 나는 그것이 객체 지향 프로그래밍의 맥락에서 필수적이라고 생각합니다.

의도적으로 남겨져 허용되지 않습니까? 아니면 과부하가 좋지 않은가?


27
함수 오버로딩은 실제로 OO 프로그래밍의 기능이 아닙니다. 하위 수준의 기능 이상-타고 다형성의 목적은 일반적으로 OO의 필요한 기능을 고려 -하지만 인수에 따라 함수 오버로딩 없습니다. 파이썬에는 인수 기반 함수 오버로드도 없습니다. 어쨌든, 함수 오버로딩은 컴파일 타임에 함수 바인딩이 발생하고 각 함수 매개 변수의 유형을 기반으로하는 정적으로 유형이 지정된 언어에서 더 실용적입니다.
Charles Salvia

2
@CharlesSalvia 좋은 답변이 될 것입니다.
kiamlaluno

1
그가 말한 것. 또한 기능 과부하가 과대 평가되었습니다. 다른 기능에 대해 동일한 기능 이름을 사용할 필요는 없습니다. 함수 이름은 비슷하지만 동일하지는 않습니다. 반면에 작업자 과부하 ...
Mr Lister

특정 질문에 대한 답변은 아니지만 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

두 개의 숫자를 더하거나 두 개의 문자열을 연결하는 기능 :

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 일뿐입니다.하지만 PHP는 놀라운 일이 아닙니다.
phant0m

10
그것은 기능 과부하가 아닙니다. 진정으로 함수를 오버로드하려면 이제 php에 해당하는을 작성하십시오 findSum(10, "steve", { 86, "2012-09-20" });. 진정한 과부하는 다른 유형의 새로운 매개 변수를 허용합니다.
Joel Etherton

3
@JoelEtherton- "오버로딩"에 대한 PHP의 해석은 대부분의 객체 지향 언어와 다릅니다. 오버로드는 전통적으로 이름은 같지만 수량과 유형이 다른 여러 메소드를 가질 수있는 기능을 제공합니다. ref : http://php.net/manual/en/language.oop5.overloading.php PHP에서 과부하는 속성과 메소드를 동적으로 "생성"하는 수단을 제공합니다. 이 동적 개체는 다양한 액션 유형에 대해 클래스에서 설정할 수있는 마법 메서드를 통해 처리됩니다.
rajukoyilandy

7
@rajukoyilandy : 다 괜찮아요.하지만 OP의 질문은 PHP가 왜 "전통적인"오버로딩을 구현하지 않는지 묻습니다. 당신의 대답은 그것을 다루지 않습니다.
Joel Etherton

7
오버로드되지 않습니다. 함수의 정의 / 선언은 여전히 ​​하나뿐입니다. 이것은 C ++의 va_list / va_arg와 같습니다. 같은 문제를 해결할 수 있습니까? 예. 그러나 여전히 과부하가 걸리지 않습니다.
Luke

13

아니 는 "전통 오버로드"를 완벽하게 지원, 단지 부분 .

정의 : "전통적 오버로드"는 메소드를 호출 할 때 이름은 같지만 수량 및 유형이 다른 여러 메소드를 가질 수있는 기능을 제공합니다 . 메소드 선언의 경우 , 오버로드 된 각 함수에 대해 별도 / 격리 된 선언을 표현하는 옵션을 제공합니다.

참고 :이 정의의 두 번째 부분은 일반적 으로 올바른 선언을 선택하기 위해 유형 확인 및 / 또는 arity 확인 을 수행하는 정적으로 유형이 지정된 프로그래밍 언어 와 관련이 있습니다. PHP는 정적 인 언어가 아니며 동적 이며 약한 타이핑을 사용 합니다.


PHP 지원 :

  • 예, 이름은 같지만 수량이 다른 여러 메소드 를 호출 하는 기능을 제공합니다 . 참조 func_get_args 및 @rajukoyilandy 대답을 우리가 사용할 수 있습니다 및 .f(x)f(x,y)

  • 예, 이름은 같지만 유형이 다른 여러 메소드 를 호출 하는 기능을 제공합니다 . 메소드에서 gettype의 내부 사용

    • BUT for reference ... 변수 만 참조로 전달할 수 있으며 상수 / 변수 감지를위한 과부하를 관리 할 수 ​​없습니다.
  • NOT은 이름은 같지만 수량이 다른 여러 메소드 를 선언 하는 기능을 제공하지 않습니다 . 우리가 호출 할 수 있기 때문이다 과 같은으로 선언.f(x)f(x,y)f

  • NOT은 이름은 같지만 유형이 다른 여러 메소드 를 선언 하는 기능을 제공하지 않습니다 . PHP 컴파일러는 동일한 함수로 해석해야하기 때문 입니다 .f($integer,$string)f($string,$integer)

"전통적인 오버로드"설명에 대해서는 PHP5 오버로드 문서 를 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.