Protocols
자바의 인터페이스, C++의 버츄얼 클래스 같은 것
상속 받은 클래스에게 이것은 꼭 구현해야 한다고 규정 짓는 것. 말 그대로 프로토콜.
Printing.h
Fraction.h
Fraction.m
Complex.h
Complex.m
main.m
결과
- The methods that the protocol requires to be implemented are not required to be in the list of methods for the header file. As you can see, Complex.h doesn't have a definition for -(void) print, but it still implements it since it conforms to the protocol.
- One unique aspect of Objective-C's interface system is how you specify types. Rather than specifying it like Java or C++ as: Printing *someVar = ( Printing * ) frac; for example, you use the id type with a restricted protocol: id <Printing> var = frac; This allows you to dynamically specify a type that requires multiple protocols, all with one variable. Such as: id <Printing, NSCopying> var = frac;
- Much like using @selector for testing an object's inheritance, you can use @protocol to test for conformance of interfaces. [object conformsToProtocol: @protocol( SomeProtocol )] returns a BOOL if the object conforms to that protocol. This works the same for classes as well: [SomeClass conformsToProtocol: @protocol( SomeProtocol )].
자바의 인터페이스, C++의 버츄얼 클래스 같은 것
상속 받은 클래스에게 이것은 꼭 구현해야 한다고 규정 짓는 것. 말 그대로 프로토콜.
Printing.h
// 프로토콜 정의 @protocol Printing -(void) print; @end |
Fraction.h
#import <Foundation/NSObject.h> #import "Printing.h" // <> 안이 프로토콜. // NSObejct를 상속하고, Printing과 NSCopying을 프로토콜로 구현 @interface Fraction: NSObject <Printing, NSCopying> { int numerator; int denominator; } -(Fraction*) initWithNumerator: (int) n denominator: (int) d; -(void) setNumerator: (int) d; -(void) setDenominator: (int) d; -(void) setNumerator: (int) n andDenominator: (int) d; -(int) numerator; -(int) denominator; @end |
Fraction.m
#import "Fraction.h" #import <stdio.h> @implementation Fraction -(Fraction*) initWithNumerator: (int) n denominator: (int) d { self = [super init]; if ( self ) { [self setNumerator: n andDenominator: d]; } return self; } // Fraction.h에는 정의 되어 있지 않으나, 프로토콜 Printing에 정의되어 있는 것을 구현 -(void) print { printf( "%i/%i", numerator, denominator ); } -(void) setNumerator: (int) n { numerator = n; } -(void) setDenominator: (int) d { denominator = d; } -(void) setNumerator: (int) n andDenominator: (int) d { numerator = n; denominator = d; } -(int) denominator { return denominator; } -(int) numerator { return numerator; } // print method와 마찬가지로 NSCopying 프로토콜을 구현 -(Fraction*) copyWithZone: (NSZone*) zone { return [[Fraction allocWithZone: zone] initWithNumerator: numerator denominator: denominator]; } @end |
Complex.h
#import <Foundation/NSObject.h> #import "Printing.h" @interface Complex: NSObject <Printing> { double real; double imaginary; } -(Complex*) initWithReal: (double) r andImaginary: (double) i; -(void) setReal: (double) r; -(void) setImaginary: (double) i; -(void) setReal: (double) r andImaginary: (double) i; -(double) real; -(double) imaginary; @end |
Complex.m
#import "Complex.h" #import <stdio.h> @implementation Complex -(Complex*) initWithReal: (double) r andImaginary: (double) i { self = [super init]; if ( self ) { [self setReal: r andImaginary: i]; } return self; } -(void) setReal: (double) r { real = r; } -(void) setImaginary: (double) i { imaginary = i; } -(void) setReal: (double) r andImaginary: (double) i { real = r; imaginary = i; } -(double) real { return real; } -(double) imaginary { return imaginary; } -(void) print { // printf( "%_f + %_fi", real, imaginary ); printf( "%f + %f", real, imaginary ); } @end |
main.m
#import <stdio.h> #import "Fraction.h" #import "Complex.h" int main( int argc, const char *argv[] ) { // create a new instance Fraction *frac = [[Fraction alloc] initWithNumerator: 3 denominator: 10]; Complex *comp = [[Complex alloc] initWithReal: 5 andImaginary: 15]; id <Printing> printable; id <NSCopying, Printing> copyPrintable; // print it printable = frac; printf( "The fraction is: " ); [printable print]; printf( "\n" ); // print complex printable = comp; printf( "The complex number is: " ); [printable print]; printf( "\n" ); // this compiles because Fraction comforms to both Printing and NSCopyable copyPrintable = frac; // this doesn't compile because Complex only conforms to Printing //copyPrintable = comp; // test conformance // true if ( [frac conformsToProtocol: @protocol( NSCopying )] == YES ) { printf( "Fraction conforms to NSCopying\n" ); } else { printf( "Fraction doesn't conform to NSCopying\n" ); } // false if ( [comp conformsToProtocol: @protocol( NSCopying )] == YES ) { printf( "Complex conforms to NSCopying\n" ); } else { printf( "Complex doesn't conform to NSCopying\n" ); } // test id type id f; // 그냥 id 타입으로 받아도 상관없음. 다만 엄격한 사용을 위해 위와 같이 protocol을 지정. f = frac; [f print]; printf( "\n" ); f = comp; [f print]; printf( "\n" ); // free memory [frac release]; [comp release]; system("PAUSE"); return 0; } |
결과
The fraction is: 3/10 The complex number is: 5.000000 + 15.000000 Fraction conforms to NSCopying Complex doesn't conform to NSCopying 3/10 5.000000 + 15.000000 계속하려면 아무 키나 누르십시오 . . . |
- The methods that the protocol requires to be implemented are not required to be in the list of methods for the header file. As you can see, Complex.h doesn't have a definition for -(void) print, but it still implements it since it conforms to the protocol.
- One unique aspect of Objective-C's interface system is how you specify types. Rather than specifying it like Java or C++ as: Printing *someVar = ( Printing * ) frac; for example, you use the id type with a restricted protocol: id <Printing> var = frac; This allows you to dynamically specify a type that requires multiple protocols, all with one variable. Such as: id <Printing, NSCopying> var = frac;
- Much like using @selector for testing an object's inheritance, you can use @protocol to test for conformance of interfaces. [object conformsToProtocol: @protocol( SomeProtocol )] returns a BOOL if the object conforms to that protocol. This works the same for classes as well: [SomeClass conformsToProtocol: @protocol( SomeProtocol )].
'프로그래밍 > iPhone Dev' 카테고리의 다른 글
[Objective C] 12 Dealloc (1) | 2009.11.12 |
---|---|
[Objective C] 11 Retain and Release (0) | 2009.11.12 |
[Objective C] 09 Posing (0) | 2009.11.10 |
[Objective C] 08 Categories (0) | 2009.11.09 |
[Objective C] 07 DynamicTypes (0) | 2009.10.30 |