2013-07-20 3 views
1

제 질문은 객체 지향 PHP의 상속 메커니즘에 관한 것입니다. 클래스 변수를 생성자와 모든 자식 클래스에서 수퍼 클래스로 초기화하여 초기화 된 변수를 사용하려면 슈퍼 클래스 생성자가 암시 적으로 호출되지 않으므로 수퍼 클래스의 생성자에서이 작업을 수행 할 수 없습니다. 자바에서와 마찬가지로 children 클래스 생성자. 모든 하위 생성자에서 수퍼 클래스 생성자를 수동으로 호출해야하는 경우 모든 자식 클래스 생성자에서 초기화를 수행하는 것만 큼 이점이 없습니다.슈퍼 클래스의 PHP 변수 초기화

이 문제를 어떻게 해결할 수 있습니까? 어떤 아이디어?

class superclass { 

    protected $a; 

    function __construct() { 
    $this->a = new Foo(); 
    } 

} 

class childrenclass1 extends superclass { 

    function __construct() { 
    do_something; 
    } 

    function childrenfunction() { 
    $this->a->method(); // not initalized; 
    } 

} 
+1

올바른 코드 샘플로 시나리오를 설명하십시오. – Lion

+0

이 도움이되는지 확인하십시오 : http://stackoverflow.com/questions/9428077/php-superclass-and-subclass – Maximus2012

+0

수퍼 클래스의 생성자에서 변수를 초기화하고이를 하위 클래스에서 사용하려는 경우 '생성자를 호출하면 부모 생성자를'parent :: __ construct()'와 같이 호출해야합니다. –

답변

2

Java와 마찬가지로 수퍼 클래스 생성자는 자식 클래스가 자체 생성자를 구현하지 않을 때만 자동으로 호출됩니다. 또는 상수 표현식 인 경우 초기 속성 값을 클래스 정의의 일부로 선언 할 수 있습니다.

그래서, 기본적으로, 당신의 선택은 다음과 같습니다

  1. 는 부모 클래스의 비 동적 값으로 변수를 초기화 : 구현하는 모든 자식 클래스에서

    protected $var = 123; 
    
  2. 사용 parent::__construct() 자신의 자신의 생성자. 부모 생성자를 사용하면 코드가 중복되지 않으므로 각 하위 클래스에서 해당 속성을 초기화하는 것보다 여전히 좋습니다.

상속 깊이는 2 인 경우 (즉, 단지 부모와 자식) 당신이 자식 생성자를 삭제하고 초기화 방법을 정의 할 수 있습니다 : 모든 자식 클래스의 초기화를 수행하지 않도록

class Parent 
{ 
    public function __construct() 
    { 
     ... 
     $this->initialize(); 
    } 

    protected function initialize() {} 
} 

class Child extends Parent 
{ 
    protected final function initialize() 
    { 
     ... 
    } 
} 
+0

고마워요.하지만 두 예제 모두 저로서는 작동하지 않습니다. 1. 요구 된 init 값이 새로운 Object()이기 때문에 불가능합니다. 2.각 하위 클래스의 변수 초기화에 비해 어떤 이점도 보지 못하기 때문에 가능하지 않습니다. 더 이상 아이디어가 없습니까? – Ferenjito

+0

@Ferenjito 개인적인 경험으로 볼 때 C++ 만 암시 적 생성자 체인을 구현합니다. 그런데, 당신은 여전히'parent :: __ construct()'를하는 것에서 몇 가지 이점을 얻는다. 왜냐하면 코드가 중복되지 않기 때문이다. –

0

이점을 생성자는 그것을 초기화하기위한 논리가 부모 생성자의 한 곳에서 유지 될 수 있다는 것입니다. 모든 자식 생성자에서 부모 생성자를 호출하는 것은 지루할 수 있지만 적어도 논리를 복제하지는 않습니다.

다른 옵션은 변수를 비공개로 설정하고 메소드를 사용하여 하위 클래스에서 변수에 액세스하는 것입니다. 이 메소드는 필요한 경우 초기화하고 값을 리턴 할 수 있습니다.

class superclass { 
    private $a; 

    protected function getA() { 
     if (!($this->a instanceof Foo)) { 
      $this->a = new Foo(); 
     } 
     return $this->a; 
    } 
} 

class childrenclass1 extends superclass { 

    public function childrenfunction() { 
     $this->getA()->method(); 
    } 
} 

... $this을 사용하여 변수 또는 방법에 액세스하는 것을 잊지 마십시오. 당신은 자바에서 할 수있는 것처럼 PHP에서 제외시킬 수 없습니다.

0

일부 생성자를 초기화하거나 다른 유용한 기능을 수행 할 수 있으므로 상위 생성자를 호출하는 것이 좋습니다. 그러나 임의의 하위 생성자 parent :: __ construct()를 작성하지 않으려면 하위 생성자 작성을 피하고 모든 것을 특수 메소드 init으로 옮길 수 있습니다.

class A { 
    public function __construct() { 
     do smt 
    } 
} 

class B extends A { 
    public function init() { 
     do smt 
    } 
} 

$b = new B(); 
$b->init(); 
+1

부모 클래스에 빈 init()이있어 부모 생성자에서 init()을 자동으로 호출합니다. – jcsanyi

+0

네, 좋은 충고! :) –