2013-07-29 3 views
3

다른 여러 클래스에서 Extender로 사용되는 클래스가 있고 한 인스턴스에서 부모 클래스의 메서드는 자식 클래스의 메서드를 다시 호출해야합니다. 이 일을하는 방법이 있습니까?부모 클래스의 자식 메서드 호출

PHP에는 abstract 클래스와 함수가 포함되어 있지만 각 자식 클래스에는이 경우에는 필요하지 않은 함수 abstract이 선언되어 있어야합니다. 예를 들어

(이 있습니다 예,없는 현실) -

Class parent{ 

    function on_save_changes(){ 

     some_parent_function(); 

     if($_POST['condition'] === 'A') : 
      // Call 'child_1_action()' 
     elseif($_POST['condition'] === 'B') : 
      // Call 'child_2_action()' 
     endif  

     some_other_parent_function(); 

    } 

    function some_parent_function(){ 
     // Do something here, required by multiple child Classes 
    } 

} 

Class child_1 Extends parent{ 

    function __construct(){ 
     $this->on_save_changes(); 
    } 

    function child_1_action(){ 
     // Do something here, only every required by this child Class 
    } 

} 

Class child_2 Extends parent{ 

    function __construct(){ 
     $this->on_save_changes(); 
    } 

    function child_2_action(){ 
     // Do something here, only every required by this child Class 
    } 

} 
+2

동일한 쿼리를 사용하는 stackoverflow에 또 다른 스레드가 있습니다 : http://stackoverflow.com/questions/1944827/php-how-to-call-function-of-a-child-class-from-parent-class – maxxon15

+0

제 질문의 두 번째 단락을 참조하십시오.이 경우 왜이 대답이 저에게 맞지 않는지 설명합니다. –

답변

7

당신은 단지 예를 들어, 아이 메소드를 호출하여이 작업을 수행 할 수 있습니다 :

if($_POST['condition'] === 'A') : 
    $this->some_parent_function(); 
    $this->child_1_action(); 

그러나 , 당신은 이것을하지 말아야합니다. 자식 클래스에만 존재하는 메서드를 호출하는 부모에게 검사를하는 것은 매우 나쁜 디자인 냄새입니다. 잘 알려진 디자인 패턴을 활용하거나 단순히 클래스 계층 구조를보다 효과적으로 생각함으로써 구조화 된 방식으로 작업을 수행하는 방법이 항상 있습니다.

부모 클래스에서 이러한 모든 메소드를 no-ops로 구현하면 매우 간단합니다. 각 자식 클래스는 관심있는 메소드를 오버라이드 (및 구현을 제공) 할 수 있습니다. 이것은 다소 기계적인 솔루션이므로 실제로는 최상의 접근 방법인지는 알 수 없지만 콜드 콜보다 훨씬 낫습니다. 기술적으로 존재할 수없는 방법.

+0

+1 나쁜 디자인의 냄새에 대한 힌트. – moonwave99

+0

답장을 보내 주셔서 감사합니다. 부모로부터 자식 메서드를 직접 호출하는 것은 작동하지 않습니다 ('Call to undefined method' 오류). 이 경우 내가 할 것은'on_save_changes()'메소드를 덮어 쓰는 것이라고 생각합니다. 먼저 몇 가지 기능을 복제해야하지만 더 나은 방법으로 클래스를 구조화하려는 것에 대해 여러분이 말하는 것에 감사드립니다. –

+0

@DavidGard : 잘못된 오류가 발생하면 잘못된 유형의 자식 객체에서 메소드를 호출하려고합니다. 이것은 확실히 호출 로직 (또는 메소드를 구현해야하지만 수행하지 않아야하는 하위 클래스)의 버그 일 뿐이지 만, 처음에는이를 수행하지 않아야하는 정확한 이유이기도합니다. – Jon

0

부모 클래스에서 자식 클래스가 자체적으로 구현해야하는 미리 정의 된 방식으로 동작 시퀀스를 만들어야하는 경우 "템플릿 메서드"패턴을 사용할 수 있습니다. 그러나 미래에 정의 된 임의의 메소드를 참조하는 것을 피해야합니다.

일반적으로 부모님이 사용하는 방법은 abstract으로 선언하거나 기본 구현을해야합니다. 아이들은이 방법을 무시할 것입니다.

abstract class parent{ 
    function on_save_changes(){ 
    some_parent_function(); 
    some_child_action(); 
    some_other_parent_function(); // added to follow changes of question 
    } 

    function some_parent_function(){ 
    // Do something here, required by multiple child Classes 
    } 

    abstract public function some_child_action(); 

} 

class child_1 Extends parent{ 
    function some_child__action(){ 
    if($_POST['condition'] === 'A') : 
     // Do something here, only every required by this child Class 
    endif; 
    } 
} 

class child_2 Extends parent{ 
    function some_child_action(){ 
    if($_POST['condition'] === 'B') : 
     // Do something here, only every required by this child Class 
    endif; 
    } 
} 
+0

하지만이 경우에도 클래스 계층 구조를 명시 적 분기 내부와 혼합하기 때문에 나쁜 디자인이라는 것을 알아야합니다. – dmitry

+0

답장을 보내 주셔서 감사합니다. 그래서이 경우 나는 내가 필요한 기능을 얻기 위해'child-> parent-> child-> parent' 가야만 할 것입니다. 기술적으로는 효과가있을 것이므로이 기법에 대해 생각해 보겠습니다. –

+0

'추상적 인'방법을 이해하고 있습니까? 확인차. 템플릿 (on_save_changes)과 논리의 골격을 만들고, 부모가 구현할 수없는 모든 메소드를 추상화하고 자식이 구현하도록 남겨 둡니다. 그것은 "템플릿 방법"패턴입니다. – dmitry

1

이 시도 :

class ParentClass{ 

    private $childActionMethod; 

    public function on_save_changes(){ 
     if(method_exists($this, $this->childActionMethod)) { 
      call_user_func_array(array($this, $this->childActionMethod), func_get_args()); 
     } 
     else { 
      throw new Exception('Child Method has not been set'); 
     } 
    } 

    protected function setChildActionMethod($methodName) { 
     $this->childActionMethod = $methodName; 
    } 
} 

class ChildClass1 extends ParentClass{ 

    function __construct(){ 
     $this->setChildActionMethod('child_1_action'); 
    } 

    function child_1_action(){ 
     echo('Hello First World<br />'); 
    } 
} 

class ChildClass2 extends ParentClass{ 

    function __construct(){ 
     $this->setChildActionMethod('child_2_action'); 
    } 

    function child_2_action(){ 
     echo('Hello Second World<br />'); 
    } 
} 

$child1 = new ChildClass1(); 
$child1->on_save_changes(); 
// Hello First World 

$child2 = new ChildClass2(); 
$child2->on_save_changes(); 
// Hello Second World 

부모 클래스는 아이들 호출 보호 방법 setChildActionMethod을 가지고 있습니다. 자식이 인스턴스화되면 부모는 부모가 저장시 호출 할 메서드의 이름을 알립니다.

메서드가 존재하면 모든 인수와 함께 호출되거나 예외를 throw합니다 (오류 처리를 변경할 수 있음).

이 패턴의 이름은 확실하지만 그 이름이 무엇인지 확신 할 수 없습니다.

+0

흥미로운 접근 방법입니다. 기술적으로는 효과가있을 것이라고 생각하지만 가능하다면 피하는 편이 낫습니다. 다소 지저분합니다. 팁을 가져 주셔서 감사합니다. –

+0

당신은 이것에 대한 깨끗한 해결책을 찾지 못할 것입니다. 부모 클래스는 자신이 선언 한 프로퍼티와 메소드의 '존재'이외에 파생 클래스에 대해 아무것도 알지 못합니다. – Flosculus

관련 문제