Feb 17, 2010

Tìm hiểu Objective - C phần 2

tiếp theo phần 1

Exception và handler.
Ngôn ngữ cũng hỗ chợ các cấu trúc try - catch - throw - finally giống như ngôn C++ @try - @catch - @throw - @finally cách thức sử dụng cũng hoàn toàn tương tự.


Categories
Là đặc điểm nếu bạn muốn mở rộng lớp bằng cách thêm mới vào lớp một phương thức. Khi bạn làm việc quen với OOP thì bạn sẽ thấy đây là một trong những thuộc tính vô cùng hữu ích của Objective C, kể cả ngay khi bạn không có mã nguồn của lớp nhưng bạn vẫn hoàn toàn có thể thêm phương thức cho lớp như thường thông qua thuộc tính này. Đặc điểm này làm giảm đi đáng kể sự kế thừa phức tạp trong C++ khi việc kế thừa chỉ để phục vụ cho việc thêm mới một phương thức. Mặt khăc việc chia mã nguồn trên nhiều files cũng giúp ích đáng kể trong việc phát triên.

#import "Fraction.h"

@interface Fraction (Math)
-(Fraction*) add: (Fraction*) f;
-(Fraction*) mul: (Fraction*) f;
-(Fraction*) div: (Fraction*) f;
-(Fraction*) sub: (Fraction*) f;
@end

File thực thi.

#import "FractionMath.h"

@implementation Fraction (Math)
-(Fraction*) add: (Fraction*) f {
return [[Fraction alloc] initWithNumerator: numerator * [f denominator] +
denominator * [f numerator]
denominator: denominator * [f denominator]];
}

-(Fraction*) mul: (Fraction*) f {
return [[Fraction alloc] initWithNumerator: numerator * [f numerator]
denominator: denominator * [f denominator]];

}

-(Fraction*) div: (Fraction*) f {
return [[Fraction alloc] initWithNumerator: numerator * [f denominator]
denominator: denominator * [f numerator]];
}

-(Fraction*) sub: (Fraction*) f {
return [[Fraction alloc] initWithNumerator: numerator * [f denominator] -
denominator * [f numerator]
denominator: denominator * [f denominator]];
}
@end

- Tên của category phải là duy nhất
- Có thể thêm bao nhiêu lần mở rộng lơp từ category là không giới hạn nhưng với tên là duy nhất.
- Thông thể bổ xung biến thành phần bằng category.
- Có thể sử dụng category để tạo ra các phương thức private. Nếu cần.

MyClass.h
#import

@interface MyClass: NSObject
-(void) publicMethod;
@end


MyClass.m
#import "MyClass.h"
#import

@implementation MyClass
-(void) publicMethod {
printf( "public method\n" );
}
@end

// private methods
@interface MyClass (Private)
-(void) privateMethod;
@end

@implementation MyClass (Private)
-(void) privateMethod {
printf( "private method\n" );
}
@end


main.m
#import "MyClass.h"

int main( int argc, const char *argv[] ) {
MyClass *obj = [[MyClass alloc] init];

// this compiles
[obj publicMethod];

// this throws errors when compiling
//[obj privateMethod];

// free memory
[obj release];
return 0;
}

cái này thật thú vị phải không, thực ra đây là một hệ quả trực tiếp từ đăc tính run-time của Objective C.


Protocals: Giao diện.
Đây hoàn toàn tương đồng với khái miện lớp ảo trong C++ hoặc gọi là giao diện trong C# và Java. Bản thân @protocals không có sự thực thi. Nếu lớp nào cam kết thực thi nó thì trong phần thực thi sẽ implement các phương thức mà protocals khai báo.

@protocol Printing
-(void) print;
@end
Fraction.h
#import
#import "Printing.h"

@interface Fraction: NSObject {
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

@implementation Fraction
-(Fraction*) initWithNumerator: (int) n denominator: (int) d {
self = [super init];

if ( self ) {
[self setNumerator: n andDenominator: d];
}

return self;
}

-(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;
}

-(Fraction*) copyWithZone: (NSZone*) zone {
return [[Fraction allocWithZone: zone] initWithNumerator: numerator
denominator: denominator];
}
@end


Complex.h
#import
#import "Printing.h"

@interface Complex: NSObject {
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

@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 );
}
@end


main.m
#import
#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 printable;
id 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" );
}

// false
if ( [comp conformsToProtocol: @protocol( NSCopying )] == YES ) {
printf( "Complex conforms to NSCopying\n" );
}

// free memory
[frac release];
[comp release];

return 0;
}



Properties
Thuộc tính gần như bất cứ một ngôn ngữ mới hiện đại nào cũng hỗ chợ khái niệm này, đây là một khái niệm bảo toàn tính đóng gói của tư tưởng OOP.
Đối vơi ngôn ngữ ObC có mốt số những hỗ chợ đặc biệt hơn một chút bạn khai báo sử dụng bằng @properties cũng giống như những ngôn ngữ khác khi bạn sử dụng thuộc tính với ObC bạn sẽ có 2 lựa chọn là @synthesize và @dynamic, với lựa chọn là @synthesize thì mặc nhiên trình biên dịch sẽ giúp bạn sinh ra các phương thức set và get trên thuộc tính. nhưng nếu bạn lựa chọn là @dynamic thì mọi việc bạn phải tự làm lấy.
hãy xem code
#import

@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- (NSString*) caption;
- (NSString*) photographer;

- (void) setCaption: (NSString*)input;
- (void) setPhotographer: (NSString*)input;

@end


#import

@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
@property (retain) NSString* caption;
@property (retain) NSString* photographer;

@end



No comments:

Post a Comment

 
Bạn có thể dùng bài viết của tôi tùy ý bạn nhưng vui lòng ghi lại rõ nguồn cung cấp
The world in a click_
Copyright © 2008 linhdkl