PHP에서 함수 오버로드 및 오버라이드는 무엇입니까?


답변:


192

오버로딩 은 비슷한 시그니처는 있지만 다른 매개 변수를 가진 함수를 정의합니다. 재정의 는 부모 클래스가 메서드를 정의했으며 파생 클래스 해당 메서드 를 재정의 하려는 파생 클래스에만 해당됩니다 .

PHP에서는 magic 메소드 만 사용하여 메소드를 오버로드 할 수 있습니다 __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"
?>

31
PHP는 과부하를 지원하지 않습니다.
Sasha Chedygov

18
그렇습니다 __call.
Jacob Relkin

50
PHP는 선택적 매개 변수를 통한 오버로드를 대체합니다.
b01

3
선택적 매개 변수의 아이디어 주셔서 감사합니다, 그것은 정말 도움이 힌트입니다
파브 PH

2
__call ()은 객체 컨텍스트에서 액세스 할 수없는 메소드가 호출 될 때 트리거됩니다. __callStatic () 정적 메소드에서 액세스 할 수없는 메소드가 호출 될 때 Megic 메소드가 트리거됩니다. PHP 컨텍스트에서 오버로드에 대한보다 자세한 예제와 설명을 얻으려면 다음을 따르십시오. PHP 오버로드
코드 버스터

107

함수 오버로딩은 다른 매개 변수 세트를 사용하여 동일한 함수 이름을 두 번 이상 정의 할 때 발생합니다. 예를 들면 다음과 같습니다.

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.


9
PHP, AFAIK에서는 함수 오버로딩을 지원하지 않습니다. 또한 관련없는 참고로, 왜 Subtraction수업을 확장 해야하는지 잘 모르겠습니다 Addition. :)
Sasha Chedygov

6
@musicfreak : 현지 시간 오전 12:40 ... 더 좋은 예를 생각할 수 없습니다.
Andrew Moore

5
이것은 PHP에서 아직 지원되지 않으며 PHP는 약한 유형의 언어 이므로이 경우 아무것도 변경되지 않으므로 절대로하지 않을 것입니다.
Crozin

2
오버로드는 서로 다른 매개 변수 세트를 사용하여 동일한 함수 이름을 두 번 (또는 여러 번) 정의 할 때만이 아닙니다. 일반적으로 오버로드는 동일한 수의 매개 변수를 사용하지만 유형이 다른 동일한 함수 이름을 두 번 (또는 여러 번) 정의 할 때도 발생합니다. PHP에서는 변수 유형 선언 (Java와 같은)이 없으므로이 일반화는 중요하지 않습니다. 나는 과부하가 무엇인지 정확성을 위해 이것을 언급하고 있습니다.
sbrbot

2
@sbrbot : 설정은 숫자와 유형을 모두 의미합니다.
Andrew Moore

22

엄밀히 말하면, 차이가 없습니다.

함수 재정의는 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'

2
PHP 5.xx는 오버로드를 지원하지 않으므로 PHP가 OOP가 아닙니다.
PHP Ferrari

30
PHP가 오버로드를 지원하지 않는 것은 아닙니다. 이해가되지 않습니다. 이 문제는 PHP가 동적 유형을 사용하기 때문에 발생합니다. 실제로 Javascript는 오버로드를 지원하지 않으며 여전히 OOP입니다. "PHP는 완전히 OOP가 아닙니다"똥은 일부 사람들이 OOP가 무엇인지 판단하기 위해 체크리스트를 사용하기로 결정했기 때문에 존재합니다.
Christian

PHP에서 명명 된 함수는 변경할 수 없습니다. PHP에서 명명 된 함수를 생성 한 후에는 내부 동작 (재정의)을 수정할 수있는 방법이 없습니다. 메서드 재정의를 의미하지 않는 한 다른 방법입니다. 첫 번째 줄에 주석을 달기 전에 전체 대답을 읽어야합니다. :)
Christian

@Christian 물론 PHP (및 기타 여러 언어)에서 재정의는 클래스에서 발생합니다 . 그렇습니다. 메소드마다 키워드 함수 가 접두어 있지만 메소드에 대해 이야기하고 있습니다 . 그러나 실제로 전체 답을 먼저 읽어야합니다.
e2-e4

9

과부하 예

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);

좋은 사용자 정의 구현이지만 언어로 제공해야합니다.
4EACH

이것은 각각의 puporse에 대해 다른 분석법 이름을 사용하는 동안 분석법, 기능 과부하가 아닙니다
TomSawyer

5

PHP가 오버로드 패러다임을 완전히 지원하지는 않지만 기본 매개 변수를 사용하여 동일한 (또는 매우 유사한) 효과를 얻을 수 있습니다 (이전에 언급 한 사람과 동일).

다음과 같이 함수를 정의하면 :

function f($p=0)
{
  if($p)
  {
    //implement functionality #1 here
  }
  else
  {
    //implement functionality #2 here
  }
}

이 함수를 호출하면

f();

하나의 기능 (# 1)을 얻지 만 다음과 같은 매개 변수로 호출하면

f(1);

다른 기능을 사용할 수 있습니다 (# 2). 이는 과부하의 영향입니다. 함수의 입력 매개 변수에 따라 다른 기능입니다.

나는 누군가 가이 함수를 f (0)으로 호출하면 어떤 기능을 얻을 수 있는지 묻습니다.


1

PHP 오버로딩은 다른 프로그래밍 언어와는 완전히 다른 의미를 가지고 있습니다. 많은 사람들이 PHP에서 오버로드가 지원되지 않으며 오버로드에 대한 일반적인 정의에 따르면 기능을 명시 적으로 사용할 수 없다고 말했습니다.

그러나 PHP에서 오버로드에 대한 올바른 정의는 완전히 다릅니다.

PHP 오버로딩은 __set () 및 __get ()과 같은 마법 메서드를 사용하여 속성 및 메서드를 동적으로 만드는 것을 말합니다. 이러한 오버로드 메소드는 액세스 할 수 없거나 선언되지 않은 메소드 또는 특성과 상호 작용할 때 호출됩니다.

다음은 PHP 매뉴얼의 링크입니다. http://www.php.net/manual/en/language.oop5.overloading.php


1

단일 클래스에서 메소드 이름은 동일하지만 매개 변수 수가 다른 둘 이상의 메소드가있는 경우 메소드 오버로드가 발생합니다. PHP는 메소드 오버로딩을 지원하지 않습니다. 메서드 재정의는 두 개의 다른 클래스에서 동일한 메서드 이름과 동일한 수의 매개 변수를 가진 두 개의 메서드를 의미하며 부모 클래스와 자식 클래스를 의미합니다.


0

둘 다 동일한 함수 이름을 포함하지만 함수 오버로드와 재정의 사이에는 약간의 차이가 있습니다. function add (float a, float b); 여기서 add () 함수가 오버로드되었습니다. 오버라이드에서 프로그래머는 오버로드에서 프로그램이 원하는 기능을 자동으로 식별 할 수있는 원하는 기능을 실행하는 몇 가지 전술을 따릅니다 ... 감사합니다!


0

오버로딩 : 실제 세계에서, 오버로딩은 누군가에게 추가 물건을 할당하는 것을 의미합니다. 실제와 마찬가지로 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

-14

PHP 5.xx는 오버로드를 지원하지 않으므로 PHP가 OOP가 아닙니다.


18
객체 지향 프로그래밍에 대한 요구 사항을 오버로드한다는 아이디어를 어디서 얻었는지 모르겠습니다.
drewish

6
파라 메트릭 다형성이 OOP의 가장 중요한 특징 중 하나이기 때문에 @drewish?
Davor

1
다형성을 OOP의 주요 정체 중 하나로 간주하면 @drewish. 그러면 컴파일을 위해 표면적으로 과부하가 발생합니다. 그러나 메서드 오버로드는 컴파일 타임 다형성이며 정적 다형성이라고도합니다.
Yasir Arefin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.