2009-12-08 6 views
0

두 개의 비슷한 클래스, MultiSlotBlockSingleSlotBlock이 있습니다. 그들은 많은 공통 코드를 공유하기 시작 했으므로 일부 리팩토링을 수행하고 일부 메소드를 새로운 수퍼 클래스로 가져 오도록 결정했습니다. Block이라고합시다.풀 업 리팩토링, Objective-C

예 단순화 내가 끌어 방법, 지금 하나는 다음과 같습니다

// (Block.mm) 

- (void)doACommonBehaviour 
{  
     // .. does some stuff 

     [self doAUniqueBehaviour]; 
} 

여기서 문제는 물론 내 슈퍼 클래스가이를 구현하지 않기 때문에 [self doAUniqueBehaviour] 경고를 보여주고 있다는 점이다 메소드를 호출 할 수 있습니다.

내가 생각한 두 가지 해결책은 나에게 큰 소리가 아닙니다. 하나는 지금과 같은 프로토콜 (나는 현재 그 일을하고있는 방식)를 사용하는 것입니다 : 다른 (이 경우에 많이있을 것입니다) 그냥 반환 내 슈퍼 클래스에 빈 메서드 본문을 가지고있다

// (Block.mm) 

- (void)doACommonBehaviour 
{  
     // .. does some stuff 

     if ([self conformsToProtocol:@protocol(UniqueBehaviourProtocol)]) 
     { 
      id<UniqueBehaviourProtocol> block = (id<UniqueBehaviourProtocol>)self; 
      [block doAUniqueBehaviour]; 
     } 
} 

doesNotRespondToSelector.

내가 전략 패턴을 사용해야한다는 것에 뭔가 이상한 생각이 들지만, 나는 벗어날 수 있으며 구현 방법을 생각하지 못했습니다.

아이디어가 있으십니까? 감사.

편집 : doAUniqueBehaviour이 모든 하위 클래스에 구현된다는 사실을 알고 있습니다. 이는 구현이 다를뿐입니다.

답변

3

슈퍼 클래스는 서브 클래스에 대해 알지 못합니다. 당신은 거기에 - (void)doACommonBehaviour 모든 서브 클래스의 방법을 구현해야합니다 :

- (void)doACommonBehaviour 
{  
     [super doACommonBehaviour]; 
     [self doAUniqueBehaviour]; 
} 

편집 - 설명 :

모든 서브 클래스가 슈퍼 클래스 (심지어 빈)에서 구현되어야 다음 -doAUniqueBehaviour을 구현하려는 경우와 각 서브 클래스는 필요에 따라 각 서브 클래스를 대체합니다.

서브 클래스 1이 -doAUniqueBehaviour1을 구현하는 경우 서브 클래스 2는 -doAUniqueBehaviour2 등을 구현하고 위에서 제안한 것을 수행합니다. 예. 디미트리의 제안은, 대신 같은 방법을 구현하기 위해 각각의 서브 클래스를 강제로 작동합니다 @

- (void)doACommonBehaviour 
{  
     [super doACommonBehaviour]; 
     [self doAUniqueBehaviour1]; 
} 
+0

모든 하위 클래스가'doAUniqueBehaviour'를 구현한다는 사실을 알고 있다면 어떻게 될까요? 슈퍼 클래스에서이 메소드의 인터페이스를 제공하고 싶습니다. 구현이 아닙니다. – Sam

+1

모두 구현 한 경우 수퍼 클래스 인 인터페이스와 구현에 추가하십시오. 그런 다음 모든 하위 클래스에서 독립적으로 재정의하십시오. – Dimitris

+0

-doAUniqueBehaviour가 일부 하위 클래스에서 구현되었다고 가정했습니다. 모든 서브 클래스에 의해 구현되고있는 경우 (다른 방법으로도), 슈퍼 클래스에 의해 구현 될 필요가 있습니다. 그리고 나서 각 서브 클래스는이 메소드를 자체적으로 구현할 때 필요한 모든 작업을 수행합니다. 어떤 경우 든 프로토콜을 필요로하지 않거나 수퍼 클래스가 서브 클래스에서 수행 할 수있는 작업을 확인할 필요가 없습니다. – Dimitris

2

Objective-C에는 abstract 클래스와 같은 개념이 없습니다. 경고를 피하기 위해 기본 클래스에서 기본 구현을 제공해야합니다. 일반적으로이 구현은 런타임에 doesNotRespondToSelector 오류가 발생합니다 :

- (id)someMethod:(SomeObject*)blah 
    [self doesNotRecognizeSelector:_cmd]; 
    return nil; 
} 

참고하십시오 _cmd 인수는 호출 선택입니다.

+0

실용적인 대안이지만, 주어진 메소드가 예외를 발생시키는 것이 아니라 "추상적 인"클래스를 인스턴스화 할 수 없기를 바랄뿐입니다. –

1

, 당신은 (헤더, 구현 파일에없는) 블록에 한 번 선언하고 단지 그 방법은 위의 수 : subclass1에서 과 같이 독특한 방법을 선언

- (void) doUniqueBehaviour { } 

- (void) doCommonBehaviour {  
    // any common code you need 
    [self doUniqueBehaviour]; 
} 

이것은 어떤 컴파일러 경고를 방지 할 수 있습니다, 당신이 원하는대로 당신은 하위 클래스에 -doUniqueBehaviour을 대체 할 수 있습니다. 또한 코드 중복을 피하고 하나의 하위 클래스에서 코드를 변경할 가능성을 줄이지 만 다른 클래스에서는 변경할 수 없습니다. 또한 별도의 프로토콜이 필요 없으며 동적 입력이 유지됩니다.

+0

예, 대답은 처음에는 -doAUniqueBehaviour가 각 하위 클래스마다 다른 것으로 가정했습니다. doAUniqueBehaviour1 doAUniqueBehaviour2 etc ...와 비슷합니다. 모든 클래스가이를 구현하면 슈퍼 클래스에 있어야합니다. – Dimitris