2012-10-28 2 views
-3

는 기본 클래스를 볼 수 있습니다이라고 , 합리적이다 $this 이후 지금은 B이고, A가 아니라. .. 그러나 나는 그것을 어떻게 피할 것인지 전혀 모른다.원하지 않는 방법은

Btw, 나는 B::renderSomethingRecursive() 메서드를 그냥 제거해야한다는 것을 알고 있지만 실수로 호출해서는 안된다는 통지로 보관하고 싶습니다. 나는 이것을 "사용할 수 없도록 만들기 위해"비공개로 만들고 싶었지만, 우리가 알다시피 그 불가능한 것 같습니다. :)

어떤 아이디어라도?

+5

재현 할 수 없습니다 두어야합니다 ','A'를 '추상'이라고 선언했다. – lanzz

+1

재생할 수 없습니다. 귀하의 질문은 무엇인가? – hakre

+2

실제 코드를 게시하십시오.이 코드는 구문 오류로 인해 실행되지 않습니다. 그것은 결코 B에서 메서드를 실행해서는 안되므로 명백하게 뭔가 잘못하고 있지만이 코드는 보이지 않습니다. –

답변

2

B에 전화를 걸지 않으려면 왜 메서드를 정의 했습니까? 그냥 정의하지 마라. PHP가 호출 할 수있는 유일한 메소드가있다. 그런 식으로, 당신은 parent::theMethod을 사용할 필요가 없습니다, 당신은 쉽게 단지

2

왜 구성보다는 상속을 선호하는 리팩토링 정말, 전부 그 this->theMethod();

Abstract class A 
{ 
    public function renderSomethingRecursive() 
    { 
     $this->renderSomethingRecursive(); // no need for self::, that's for static calls 
    } 

    abstract public function addSomething (value); 
} 

class B extends A 
{ 
    public function addSomething (value) 
    { 
     $this->renderSomethingRecursive();//calls the abstract method as though it were defined in class B 
    } 
} 

를 사용하여 호출 할 수 있습니다? '무언가 추가'와 '재귀 적 무언가'를 별도의 관심사로 나누기 시작하면 함께 잘 어울리는 작고 이해하기 쉬운 수업을 찾을 수 있습니다.

B의 발신자가 renderSomethingRecursive()에 전화를 걸 수 없으므로 클래스에서 기능을 완전히 제거하십시오. 또한 상속을 깨고, BA에서 상속 할 필요가 없습니다. 우리는 여전히 B에 'stuff stuff'을 추가하여 addSomething()이라는 기능을 유지하려고합니다. 두 클래스에서 addSomething의 본문을 복제하고 싶지 않으므로 이 호출 될 때마다 A의 인스턴스에 위임하도록 B을 가져올 수 있습니다.

abstract class A 
{ 
    public function renderSomethingRecursive() 
    { 
     // this function can call itself 
     self::renderSomethingRecursive(); 
    } 

    abstract function addSomething ($value) { 

} 

class AA extends A 
{ 
    public function addSomething($value) 
    { 
     // something, something, something.... 
     self::renderSomethingRecursive(); 
    } 
} 


class B 
{ 
    private $a; 
    public function __construct(A $a) 
    { 
     $this->a = $a; 
    } 

    public function addSomething ($value) { 
     $this->a->addSomething($value); 
    } 
} 

$obj = new B(new AA()); 
$obj->addSomething(....); 

이 더 나은 이미지고, 그러나 우리는 우리가 완료되기 전에 addSomething 중복이 제거 할 수 있습니다. 목록을 렌더링하고 관리하는 것은 실제로 두 가지 다른 관심사이므로이를 분할 할 수 있습니다. 먼저 addSomethingB으로 옮깁니다. 그런 다음 renderSomethingRecursive이 $ 데이터에 대한 액세스 권한을 필요로 함을 알고 있습니다. 일부 매개 변수를 추가하여 해당 데이터에 다시 액세스 할 수 있습니다. A은 더 이상 추상적 일 필요는 없지만 의 구현이 여전히 다른 경우 일 수 있습니다. B 일 수 있습니다. 코드가 결코 B : renderSomethingRecursive는()`(I은 충분히 실행 얻을를 수정 한`호출하지, 즉 제거`값 - 당신은 ...이 같은 뭔가

class A 
{ 
    public function renderSomethingRecursive($data) 
    { 
     // this function can call itself 
     self::renderSomethingRecursive($data); 
    }  
} 

class B 
{ 
    private $a; 
    private $data; 
    public function __construct(A $a) 
    { 
     $this->a = $a; 
    } 

    public function addSomething ($value) { 
     // something, something, something.... 
     // append to $this->data probably 
     $this->a->renderSomethingRecursive($this->data); 
    } 
} 

$obj = new B(new AA()); 
$obj->addSomething(....); 
+1

이것이 우리가 OO 언어를 전혀 사용하지 않은 이유입니다. 요점은 가능할 때마다 이러한 종류의 구조를 피하는 것이 었습니다. 게다가, 'A'는 _abstract_ 클래스이며 인스턴스화 할 수 없습니다.또한 다른 객체의 속성 인 객체는 객체의 메서드에 액세스 할 수없고 그 반대의 경우도 (보호 된 액세스가 없음) 기억하십시오. 거의 : 메서드를 만들려면 _type hinting_을 사용하는 것이 가장 좋습니다 : public function __construct (A $ a)'잘못된 객체가 생성자에 전달되는 것을 피하기 위해 –

+1

엘리어스, 생성자에서 힌트 유형을 생략하는 것이 맞습니다.이를 포함하여 예제를 업데이트 할 것입니다. 이런 종류의 구조를 피하는 것에 대해서는 동의하지 않지만, OOP를하는 프로그래머가 너무 많이 확장성에 너무 집중하고 구성이 충분하지 않다는 것이 내 생각입니다. 이는 두 가지 솔루션의 주요 차이점입니다. – Ryan953

+0

내 코드를 수정하려고했는데 ... 완전히 작동하지 않는 코드로 다시 시작합니다. –