Objective-C开发指南--2

 
    • 异常情况(Exceptions)
      • 注意:异常处理只有 Mac OS X 10.3 以上才支持。
      • 基于 "Programming in Objective-C," Copyright © 2004 by Sams Publishing一书中的范例,并经过允许而刊载。
      • CupWarningException.h

§                             #import <Foundation/NSException.h>

§                              

§                             @interface CupWarningException: NSException

@end

      • CupWarningException.m

§                             #import "CupWarningException.h"

§                              

§                             @implementation CupWarningException

@end

      • CupOverflowException.h

§                             #import <Foundation/NSException.h>

§                              

§                             @interface CupOverflowException: NSException

@end

      • CupOverflowException.m

§                             #import "CupOverflowException.h"

§                              

§                             @implementation CupOverflowException

@end

      • Cup.h

§                             #import <Foundation/NSObject.h>

§                              

§                             @interface Cup: NSObject {

§                                 int level;

§                             }

§                              

§                             -(int) level;

§                             -(void) setLevel: (int) l;

§                             -(void) fill;

§                             -(void) empty;

§                             -(void) print;

@end

      • Cup.m

§                             #import "Cup.h"

§                             #import "CupOverflowException.h"

§                             #import "CupWarningException.h"

§                             #import <Foundation/NSException.h>

§                             #import <Foundation/NSString.h>

§                              

§                             @implementation Cup

§                             -(id) init {

§                                 self = [super init];

§                              

§                                 if ( self ) {

§                                     [self setLevel: 0];

§                                 }

§                              

§                                 return self;

§                             }

§                              

§                             -(int) level {

§                                 return level;

§                             }

§                              

§                             -(void) setLevel: (int) l {

§                                 level = l;

§                              

§                                 if ( level > 100 ) {

§                                     // throw overflow

§                                     NSException *e = [CupOverflowException

§                                         exceptionWithName: @"CupOverflowException"

§                                         reason: @"The level is above 100"

§                                         userInfo: nil];

§                                     @throw e;

§                                 } else if ( level >= 50 ) {

§                                     // throw warning

§                                     NSException *e = [CupWarningException

§                                         exceptionWithName: @"CupWarningException"

§                                         reason: @"The level is above or at 50"

§                                         userInfo: nil];

§                                     @throw e;

§                                 } else if ( level < 0 ) {

§                                     // throw exception

§                                     NSException *e = [NSException

§                                         exceptionWithName: @"CupUnderflowException"

§                                         reason: @"The level is below 0"

§                                         userInfo: nil];

§                                     @throw e;

§                                 }

§                             }

§                              

§                             -(void) fill {

§                                 [self setLevel: level + 10];

§                             }

§                              

§                             -(void) empty {

§                                 [self setLevel: level - 10];

§                             }

§                              

§                             -(void) print {

§                                 printf( "Cup level is: %i\n", level );

§                             }

@end

      • main.m

§                             #import "Cup.h"

§                             #import "CupOverflowException.h"

§                             #import "CupWarningException.h"

§                             #import <Foundation/NSString.h>

§                             #import <Foundation/NSException.h>

§                             #import <Foundation/NSAutoreleasePool.h>

§                             #import <stdio.h>

§                              

§                             int main( int argc, const char *argv[] ) {

§                                 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

§                                 Cup *cup = [[Cup alloc] init];

§                                 int i;

§                              

§                                 // this will work

§                                 for ( i = 0; i < 4; i++ ) {

§                                     [cup fill];

§                                     [cup print];

§                                 }

§                              

§                                 // this will throw exceptions

§                                 for ( i = 0; i < 7; i++ ) {

§                                     @try {

§                                         [cup fill];

§                                     } @catch ( CupWarningException *e ) {

§                                         printf( "%s: ", [[e name] cString] );

§                                     } @catch ( CupOverflowException *e ) {

§                                         printf( "%s: ", [[e name] cString] );

§                                     } @finally {

§                                         [cup print];

§                                     }

§                                 }

§                              

§                                 // throw a generic exception

§                                 @try {

§                                     [cup setLevel: -1];

§                                 } @catch ( NSException *e ) {

§                                     printf( "%s: %s\n", [[e name] cString], [[e reason] cString] );

§                                 }

§                              

§                                 // free memory

§                                 [cup release];

§                                 [pool release];

}

      • output

§                             Cup level is: 10

§                             Cup level is: 20

§                             Cup level is: 30

§                             Cup level is: 40

§                             CupWarningException: Cup level is: 50

§                             CupWarningException: Cup level is: 60

§                             CupWarningException: Cup level is: 70

§                             CupWarningException: Cup level is: 80

§                             CupWarningException: Cup level is: 90

§                             CupWarningException: Cup level is: 100

§                             CupOverflowException: Cup level is: 110

CupUnderflowException: The level is below 0

      • NSAutoreleasePool 是一个内存管理类别。现在先别管它是干嘛的。
      • Exceptions(异常情况)的丢出不需要扩充(extend)NSException 对象,你可简单的用 id 来代表它: @catch ( id e ) { ... }
      • 还有一个 finally 区块,它的行为就像 Java 的异常处理方式,finally 区块的内容保证会被呼叫。
      • Cup.m 里的 @"CupOverflowException" 是一个 NSString 常数物件。在 Objective-C 中,@ 符号通常用来代表这是语言的衍生部分。C 语言形式的字符串(C string)就像 C/C++ 一样是 "String constant" 的形式,型别为 char *。
  • 继承、多型(Inheritance, Polymorphism)以及其它对象导向功能
    • id 型别
      • Objective-C 有种叫做 id 的型别,它的运作有时候像是 void*,不过它却严格规定只能用在对象。Objective-C 与 Java 跟 C++ 不一样,你在呼叫一个对象的 method 时,并不需要知道这个对象的型别。当然这个 method 一定要存在,这称为 Objective-C 的讯息传递。
      • 基于 "Programming in Objective-C," Copyright © 2004 by Sams Publishing一书中的范例,并经过允许而刊载。
      • Fraction.h

§                             #import <Foundation/NSObject.h>

§                              

§                             @interface Fraction: NSObject {

§                                 int numerator;

§                                 int denominator;

§                             }

§                              

§                             -(Fraction*) initWithNumerator: (int) n denominator: (int) d;

§                             -(void) print;

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

§                             }

§                              

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

§                             }

@end

      • Complex.h

§                             #import <Foundation/NSObject.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;

§                             -(void) print;

§                              

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

§                             }

§                              

@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: 1 denominator: 10];

§                                 Complex *comp = [[Complex alloc] initWithReal: 10 andImaginary: 15];

§                                 id number;

§                              

§                                 // print fraction

§                                 number = frac;

§                                 printf( "The fraction is: " );

§                                 [number print];

§                                 printf( "\n" );

§                              

§                                 // print complex

§                                 number = comp;

§                                 printf( "The complex number is: " );

§                                 [number print];

§                                 printf( "\n" );

§                              

§                                 // free memory

§                                 [frac release];

§                                 [comp release];

§                              

§                                 return 0;

}

      • output

§                             The fraction is: 1 / 10

The complex number is: 10.000000 + 15.000000i

      • 这种动态连结有显而易见的好处。你不需要知道你呼叫 method 的那个东西是什么型别,如果这个对象对这个讯息有反应,那就会唤起这个 method。这也不会牵涉到一堆繁琐的转型动作,比如在 Java 里呼叫一个整数对象的 .intValue() 就得先转型,然后才能呼叫这个 method。
    • 继承(Inheritance)
      • 基于 "Programming in Objective-C," Copyright © 2004 by Sams Publishing一书中的范例,并经过允许而刊载。
      • Rectangle.h

§                             #import <Foundation/NSObject.h>

§                              

§                             @interface Rectangle: NSObject {

§                                 int width;

§                                 int height;

§                             }

§                              

§                             -(Rectangle*) initWithWidth: (int) w height: (int) h;

§                             -(void) setWidth: (int) w;

§                             -(void) setHeight: (int) h;

§                             -(void) setWidth: (int) w height: (int) h;

§                             -(int) width;

§                             -(int) height;

§                             -(void) print;

@end

      • Rectangle.m

§                             #import "Rectangle.h"

§                             #import <stdio.h>

§                              

§                             @implementation Rectangle

§                             -(Rectangle*) initWithWidth: (int) w height: (int) h {

§                                 self = [super init];

§                              

§                                 if ( self ) {

§                                     [self setWidth: w height: h];

§                                 }

§                              

§                                 return self;

§                             }

§                              

§                             -(void) setWidth: (int) w {

§                                 width = w;

§                             }

§                              

§                             -(void) setHeight: (int) h {

§                                 height = h;

§                             }

§                              

§                             -(void) setWidth: (int) w height: (int) h {

§                                 width = w;

§                                 height = h;

§                             }

§                              

§                             -(int) width {

§                                 return width;

§                             }

§                              

§                             -(int) height {

§                                 return  height;

§                             }

§                              

§                             -(void) print {

§                                 printf( "width = %i, height = %i", width, height );

§                             }

@end

      • Square.h

§                             #import "Rectangle.h"

§                              

§                             @interface Square: Rectangle

§                             -(Square*) initWithSize: (int) s;

§                             -(void) setSize: (int) s;

§                             -(int) size;

@end

      • Square.m

§                             #import "Square.h"

§                              

§                             @implementation Square

§                             -(Square*) initWithSize: (int) s {

§                                 self = [super init];

§                              

§                                 if ( self ) {

§                                     [self setSize: s];

§                                 }

§                              

§                                 return self;

§                             }

§                              

§                             -(void) setSize: (int) s {

§                                 width = s;

§                                 height = s;

§                             }

§                              

§                             -(int) size {

§                                 return width;

§                             }

§                              

§                             -(void) setWidth: (int) w {

§                                 [self setSize: w];

§                             }

§                              

§                             -(void) setHeight: (int) h {

§                                 [self setSize: h];

§                             }

@end

      • main.m

§                             #import "Square.h"

§                             #import "Rectangle.h"

§                             #import <stdio.h>

§                              

§                             int main( int argc, const char *argv[] ) {

§                                 Rectangle *rec = [[Rectangle alloc] initWithWidth: 10 height: 20];

§                                 Square *sq = [[Square alloc] initWithSize: 15];

§                              

§                                 // print em

§                                 printf( "Rectangle: " );

§                                 [rec print];

§                                 printf( "\n" );

§                              

§                                 printf( "Square: " );

§                                 [sq print];

§                                 printf( "\n" );

§                              

§                                 // update square

§                                 [sq setWidth: 20];

§                                 printf( "Square after change: " );

§                                 [sq print];

§                                 printf( "\n" );

§                              

§                                 // free memory

§                                 [rec release];

§                                 [sq release];

§                                 

§                                 return 0;

}

      • output

§                             Rectangle: width = 10, height = 20

§                             Square: width = 15, height = 15

Square after change: width = 20, height = 20

      • 继承在 Objective-C 里比较像 Java。当你扩充你的 super class(所以只能有一个 parent),你想自订这个 super class 的 method,只要简单的在你的 child class implementation 里放上新的实作内容即可。而不需要 C++ 里呆呆的 virtual table。
      • 这里还有一个值得玩味的地方,如果你企图像这样去呼叫 rectangle 的 constructor: Square *sq = [[Square alloc] initWithWidth: 10 height: 15],会发生什么事?答案是会产生一个编译器错误。因为 rectangle constructor 回传的型别是 Rectangle*,而不是 Square*,所以这行不通。在某种情况下如果你真想这样用,使用 id 型别会是很好的选择。如果你想使用 parent 的 constructor,只要把 Rectangle* 回传型别改成 id 即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值