2010-05-31 5 views
19

어떻게 든 파생 클래스가 항상 재정의 된 메서드 기반을 호출하도록 할 수 있습니까? C에서 기본 메서드가 호출되도록하십시오

public class BaseClass 
{ 
    public virtual void Update() 
    { 
     if(condition) 
     { 
      throw new Exception("..."); // Prevent derived method to be called 
     } 
    } 
} 

그리고 파생 클래스에서

:

public override void Update() 
{ 
    base.Update(); // Forced call 

    // Do any work 
} 

내가 검색 한 가상이 아닌 업데이트()뿐만 아니라 보호 된 가상 UpdateEx()를 사용하는 제안을 발견했습니다. 다만 아주 청초하게 느끼지 않는다, 거기 더 나은 방법 있는가?

나는 당신이 질문을하기를 바랍니다. 그리고 나는 나쁜 영어로 유감입니다.

답변

26

template method pattern 사용 - 일부 작업을 수행해야하는 기본 메소드를 대체하지 말고 기본 클래스에서 추상 또는 노 작업이 될 수있는 특정 비트를 대체하십시오. (기본 클래스가 구체적 클래스로서 독자적으로 이해할 수 있을까요?)

기본적으로 당신이 가진 패턴 인 것처럼 들리지만 UpdateEx으로 발견 - 보통 UpdateImpl 또는 내 경험과 비슷한 것입니다. 필자는 모든 파생 클래스가 기본 코드를 호출하는 동일한 코드를 작성하도록 강요하는 아이디어를 피합니다.

+2

템플릿 메서드 패턴이 자주 사용되는 것이 좋지만 BCL은 "기본 클래스 메서드를 호출해야합니다"(anti?) 패턴을 많이 사용한다는 점에 유의해야합니다. 특히 Windows Forms 클래스에 해당합니다. – hemp

+0

두 레벨의 계층 구조를 가지고 있다면 모든 레벨에서 기본 호출을 계속 강요하고 싶다면'UpdateImpl2'가 필요합니까? –

+1

@DirkBoer : 모든 "손자"클래스가 호출되는 세 가지 메소드로 끝나야한다는 것을 의미합니까? 그렇다면 그렇습니다. 그 시점에서 디자인을 단순화하려고합니다. –

2

발견 한 제안이 좋다고 생각합니다.

기본 클래스 생성자에서 하위 클래스를 호출하는 것을 피할 수없는 유일한 기본 클래스 메서드입니다.

2

가상의 "후크"를 호출 할 수있는 가상이 아닌 기본 멤버가 있어야 문제를 해결할 수있는 가장 일반적인 솔루션이라고 생각합니다.

사용 사례에 따라 대신 event을 사용할 수 있지만 이벤트 구현을위한 일반적인 패턴은 이벤트 핸들러를 추가하는 대신 하위 클래스가 재정의 할 수있는 가상 OnEvent 메서드를 갖는 것입니다. 그것은 똑같은 것으로 귀결됩니다.

2

업데이트와 UpdateEx의 모습을 얻는 데 약간 시간이 걸렸습니다. 다른 사람들을 도울 수있는 코드 예제가 있습니다.

public class BaseClass 
{ 
    // This is the Update that class instances will use, it's never overridden by a subclass 
    public void Update() 
    { 
     if(condition); 
     // etc... base class code that will always run 

     UpdateEx(); // ensure subclass Update() functionality is run 
    } 

    protected virtual void UpdateEx() 
    { 
     // does nothing unless sub-class overrides 
    } 
} 

하위 클래스에는 Update()에 대한 구현이 없습니다. UpdateEx()를 사용하여 Update()에 구현을 추가합니다.

public class ConcreteClass : BaseClass 
{ 
    protected override void UpdateEx() 
    { 
     // implementation to be added to the BaseClass Update(); 
    } 
} 

ConcreteClass의 모든 인스턴스가 ConcreteClass가 UpdateEx로를 확장하지만 함께 업데이트의 BaseClass로 구현()를 사용합니다().

관련 문제