PHP에서 부모 메서드를 호출하는 여러 방법


90

처음에는 생성자의 두 메서드 호출이 왜 작동하는지 혼란 스러웠지만 이제는 이해한다고 생각합니다. 확장 클래스는 마치 클래스 자체에서 선언 된 것처럼 부모의 메서드를 상속하고 메서드는 부모에 있으므로 둘 다 작동합니다.

선호하는 방법 방법을 (를 통해 호출 (즉, 가장 좋은 방법)이 있다면 지금은 궁금하네요 parent또는 this어떤주의 사항이있을 경우), 이러한 동일한 코드를 실행 진정으로 동일한 방법으로하고 있는지 여부, 이상을 사용하는 경우 다른 하나.

죄송합니다. 아마 생각을 너무 많이했을 것입니다.

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

        $this->get_species();
        parent::get_species();

    }

}

$spike = new Dog;

답변:


120

부모 클래스에서 메서드가 종료되는 하위 클래스에서 메서드를 호출하는 세 가지 시나리오 (생각할 수 있음)가 있습니다.

  1. 메서드는 하위 클래스에 의해 덮어 쓰여지지 않고 부모에만 존재합니다.

    이것은 귀하의 예제와 동일하며 일반적으로 사용하는 것이 더 좋습니다 $this -> get_species(); .이 경우 두 가지가 사실상 동일하지만 메서드가 하위 클래스에 의해 상속되었으므로 구별 할 이유가 없다는 것이 맞습니다. 를 사용 $this하면 상속 된 메서드와 로컬로 선언 된 메서드간에 일관성을 유지할 수 있습니다.

  2. 메서드는 하위 클래스에 의해 덮어 쓰여지고 부모로부터 완전히 고유 한 논리를 갖습니다.

    이 경우 $this -> get_species();부모의 메서드 버전이 실행되는 것을 원하지 않기 때문에 분명히 사용하고 싶을 것 입니다. 다시 말하지만을 지속적으로 사용 $this하면이 경우와 첫 번째 경우의 차이에 대해 걱정할 필요가 없습니다.

  3. 메서드는 부모 클래스를 확장하여 부모 메서드가 달성하는 것에 추가합니다.

    이 경우에도 `$this -> get_species();하위 클래스의 다른 메서드에서 메서드를 호출 할 때 계속 사용하려고합니다 . 부모 메서드를 호출 할 위치는 부모 메서드를 덮어 쓰는 메서드에서입니다. 예:

    abstract class Animal {
    
        function get_species() {
    
            echo "I am an animal.";
    
        }
    
     }
    
     class Dog extends Animal {
    
         function __construct(){
    
             $this->get_species();
         }
    
         function get_species(){
    
             parent::get_species();
             echo "More specifically, I am a dog.";
         }
    }
    

재정의 메서드 외부에서 부모 메서드를 직접 호출해야하는 유일한 시나리오는 두 가지 다른 작업을 수행하고 로컬이 아닌 부모의 메서드 버전이 필요하다는 것을 알고있는 경우입니다. 이럴 필요는 없지만, 그 자체가 존재한다면, 이에 접근하는 깔끔한 방법 get_parentSpecies()은 부모 메서드를 호출하는 것과 같은 이름으로 새 메서드를 만드는 것입니다 .

function get_parentSpecies(){

     parent::get_species();
}

다시 말하지만 이것은 모든 것을 멋지고 일관되게 유지하여 부모 메서드에 의존하는 대신 로컬 메서드를 변경 / 수정할 수 있도록합니다.


"확장"없이 어떻게 할 수 있습니까? "인간"클래스 안에 "다리"가 있지만 부모의 "인간"기능이 필요하지 않기 때문에 확장 할 필요가 없습니다. 내가 만든 경우 지금, $leg = new leg()내부를 human, 내가 어떻게 다리 인스턴스 내부에서 인간의 함수를 호출하는 것 $leg?
user151496

@ user151496 다리는 인간의 하위 클래스가 아닙니다. 인간은 다리가 많지만 다리는 인간이 아닙니다. 그러므로 다리는 인간이 아니기 때문에 인간에게서 물려받은 다리 클래스를 가져서는 안됩니다.
Beetle

Leg를 Leggy의 인터페이스를 가진 클래스로 만드시겠습니까? 아니면 Human 클래스가 Leggy를 구현하도록 하시겠습니까? 다리가 인간에게만 국한되지 않고 인간의 다리가 인간의 고유 한 속성이며 인간의 일반적인 속성임을 어떻게 가장 잘 정의 할 수 있습니까?
안토니

2
paamayim nekudotayim은 약간 혼란 스럽습니다. 언뜻 보면 정적 메서드를 호출하는 것처럼 보입니다. 대신) (> get_species 학부모있었습니다한다
peterchaula

동의합니다. 정적 호출은 여러 측면에서 매우 혼란 스럽습니다. 나는 이것을 언젠가 업데이트해야한다.
Anthony

5

질문을 오해하지 않는 한, 나는 거의 항상 $ this-> get_species를 사용합니다. 왜냐하면 서브 클래스 (이 경우에는 개)가 그것을 확장하기 때문에 그 메서드를 덮어 쓸 수 있기 때문입니다. dog 클래스가 메서드를 재정의하지 않으면 두 가지 방법이 기능적으로 동일하지만 향후 어느 시점에서 dog의 get_species 메서드가 "dog"을 인쇄해야한다고 결정하면 모든 코드를 다시 살펴 봐야합니다. 그것을 바꾸십시오.

$ this를 사용하면 실제로 생성 한 객체의 일부이므로 항상 최신 상태가됩니다 (사용중인 속성이 객체의 수명 동안 어떻게 든 변경된 경우). 정적 클래스 메서드를 호출하고 있습니다.


메서드를 재정의하려는 경우 $ this를 사용하는 것이 좋습니다. 감사합니다
제리
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.