2013-02-14 3 views
5

대상에서 -c?Protocol vs Inheritance를 사용할 때의 장단점은 무엇입니까?

나는 수업을 만들었고, 나는 첫 수업과 같은 또 다른 수업을 원한다고 결정했다. 프로토콜을 사용하여 두 클래스 모두 해당 프로토콜을 지원해야합니까? 아니면 상위 클래스를 만들어 두 클래스가 하나의 클래스에서 상속해야한다고 결정해야합니까?

참고 :

클래스는 다음과 같습니다 비즈니스, 카탈로그, AddressAnnotation는 (현재는 사업에만 작동) 및 AddressAnnotationView는 (현재 사업에만에서만 작동). 나는 카탈로그에서 같은 일을하고 싶다. 또한 어노테이션이 서로 뭉친 시간을 관리하는 BGGoogleMapCacheForAllAnnotations (카탈로그 및 비즈니스 용 AddressAnnotation을 모두 처리 할 수 ​​있어야 함), 부모 클래스로 바꾸고 싶은 BGGoogleMap View Controller가 있습니다.

+0

첫 번째 수업은 무엇이며 두 번째 수업은 무엇입니까? 그들은 공통점이 얼마나 있습니까? 이 질문은 하나 이상의 특정 시나리오에 대해 질문하는 경우 더 나을 것입니다. 끝내기 위해 투표를하지는 않지만 쉽게 대답 할 수있는 질문이 너무 광범위하다는 것을 지적합니다. – paulmelnikow

답변

7

프로토콜을 사용하는 경우 두 클래스 유형에서 공유하는 메소드를 두 번 정의해야합니다. 프로토콜은 일반적으로 보안을 추가하고 실수를 저 지르거나 클래스 계층에 이미 포함 된 여러 클래스가 공통 메서드를 공유하고이 공유를 문서화해야 할 때 위임 패턴과 같은 특정 패턴 용으로 예약되어 있습니다. 어떤 방법으로. 한 클래스를 다른 클래스의보다 특수화 된 버전으로 나타낼 수 있다면 상속 받아야합니다.

예를 들어 게임에서 주위를 돌아 다니는 등 모든 종류의 작업을 수행하는 방법을 알고있는 Vehicle 클래스가 있다고 가정 해 보겠습니다. Car 클래스를 만들고 싶다면 Vehicle 클래스를 서브 클래스 화하여 모든 메소드 구현을 상속받을 수 있습니다. 슈퍼 클래스의 구현을 호출하기 전에 서브 클래스에 특정한 태스크를 수행하는 등, 자신의 메소드 버전을 도매하거나 구현할 수도있다. 서브 클래 싱은 수퍼 클래스의 특성과 동작을 어떤 식 으로든 수정하면서 상속 받기를 원하는 경우에 사용됩니다. 카테고리를 사용하여 추가 데이터를 입력해야하는 경우 (예 : Class Extension 일 수 있음) (이는 종종 개인 인터페이스의 일종으로 간주 됨) 인스턴스 변수와 같은 추가 데이터를 클래스에 추가해야하는 경우에 특히 그렇습니다. 일반적으로 하위 클래스는 결과적으로 수퍼 클래스보다 더 특수한 용도로 사용됩니다.

프로토콜은 단지 프로토콜입니다. 클래스가 작동하지 않을 때 컴파일러 경고를 발생시켜 모든 객체가 예상 한대로 작동하도록합니다. 위임과 같은 패턴에서는 위임이 캡슐화를 위반하는 것 이외에 필요한 메서드를 구현하고 대리인의 개체 유형을 알 수있는 유일한 방법이므로 중요합니다. 예를 들어, 내 프로젝트 중 하나에서 아래 코드를보십시오.

//SGSprite.h 
@protocol SGSpriteDelegate 
    - (BOOL) animation:(int)animationIndex willCompleteFrameNumber:(int)frame forSprite:(id)sender; 
@end 

@interface SGSprite : NSObject 
@property (nonatomic, assign) id<SGSpriteDelegate> delegate; 
@end 

//SGViewController.h 
@interface SGViewController : UIViewController <SGSpriteDelegate> 
    //...dreadfully boring stuff 
@end 

많은 클래스는 질감 된 2D 쿼드 렌더링에 내 SGSprite 클래스를 사용합니다. 때로는 스프라이트가 특정 프레임의 애니메이션에 도달하는 시점을 알아야하기 때문에 SGSprite 인스턴스는 특정 프레임에 도달했을 때이를 알 수 있도록 대리자의 메서드를 호출해야합니다. 이 클래스의 인스턴스에 대한 위임자가이 메서드를 구현하는지 확인하는 유일한 방법은 실제로 대리자가 아닌 개체를 할당하려고 할 때 프로토콜을 사용하는 것입니다. 단순히 대리자를 일반화하면 단순히 구현을 찾을 수 없기 때문에 위임자에서이 메서드를 호출 할 때마다 경고 메시지가 표시됩니다. 위임자의 헤더를 가져 오거나 대리자를 정적으로 입력하면 클래스는 더 이상 잘 캡슐화되지 않습니다.

대부분의 경우 기술적으로 프로토콜이 필요하지 않습니다. 당신은 프로토콜을 사용하지 않고 모든 클래스를 정의 할 수 있습니다. 모든 클래스는 보통이 프로토콜을 따르며 모든 것이 잘 동작 할 것입니다. 그러나 이러한 일반적인 방법은 더 이상 문서화되지 않았습니다. 따라서 특정 클래스 나 익명 객체가 구현할 필요가있는 메소드를 구현한다는 보안 이외에도 무엇이 어떻게 수행되는지 신속하게 알릴 수 있습니다. 프로토콜은 클래스 또는 클래스 인스턴스가 어떤 메소드를 구현하는지 확인해야 할 때, 특히 객체의 유형을 캡슐화 된 클래스로 유지하지 않아야하는 경우에 적합합니다.

+0

이것은 훨씬 더 좋은 대답입니다. –

+0

@JimThio 감사합니다. 나는 그것에 잠시 머물렀다. – Metabble

+0

프로토콜에 대해 고려해야 할 또 하나의 사항은 코드 작업자입니다. 자신의 프로젝트에서 일하는 개별 개발자로서 프로토콜 설정의 선택은 주로 자신의 워크 플로와 환경 설정에 따라 결정됩니다. 팀에서 일하는 중이거나 나중에 다른 사람에게 프로젝트를 넘겨 주려는 경우 다른 개발자가 자신의 코드를 사용하도록 도와주는 중요한 조직 도구가 될 수 있습니다. –

3

그 결정에 영향을 줄 수있는 요소가 많이 있습니다. 다른 클래스가 "1 등 클래스"라고 말하면, 그 의미는 무엇입니까? 즉, 동일한 클래스의 90 %를 정확히 동일하게 수행한다는 의미입니까? 방법은? 그들은 많은 것들을 똑같은 종류로 수행 할 것인가, 각각 약간 다른 방식으로 수행 할 것인가?

1 단계의 기존 방법 중 많은 부분이 그대로 수정되거나 거의 수정되지 않으면 두 번째 클래스에서 서브 클래 싱을 사용하면 방법은 "무료"그래서 당신은 단지 차이에 집중할 수 있습니다. 그러나 대부분의 코드를 다시 작성해야하고 두 클래스를 유사한 작업을 수행하는 것으로 정의하려는 경우 프로토콜이 더 적합 할 수 있습니다.

개인적으로 서브 클래 싱을 주로 사용했는데 그 이유는 프로토콜이 내 코드에서 내게 의미가있는 상황에 직면하지 않았기 때문입니다. 물론 당분간은 의식적인 결정보다 습관이 더 낫습니다. 핵심 데이터를 사용하여 응용 프로그램을 변환하기 시작했을 때, Core Data가 상속 된 속성 및 관계로 하위 항목을 만들 수있는 기능을 제공하기 때문에 서브 클래스 화가 매우 적합합니다. 따라서 개념적으로 파악하기가 쉬워졌습니다.

현재 코드를 생각하면 NSObject, 뷰 컨트롤러 등 하위 클래스로 분류하고 프로토콜 (NSCoding, 대리자보기 등)을 사용하고있을 가능성이 있습니다. 기존 클래스 및 프로토콜을 사용하는 방법과 이러한 유스 케이스가 자신의 클래스에 어떻게 적용되는지 생각해보십시오.

+0

이해하기 쉽습니다. 멋지게 설명했다. – viral

관련 문제