在Objective C入门中我们了解了如何定义类,类的实现,以及调用类函数的方式。现在再来看一看关于类的高级概念。
id,动态绑定
#import <stdio.h> #import "Bank.h" int main( int argc, const char *argv[] ) { Bank *bank1= [[Bank alloc] init]; Bank *bank2= [[Bank alloc] init]; id b; //可以把任何对象赋值给b [bank1 addAmount: 1]; b = bank1; [b print]; //调用bank1的print函数 b = bank2; [b print]; //调用bank2的print函数 // true if ( [bank1 isMemberOfClass: [Bank class]] == YES ) { printf( "bank1是Bank类的一个对象\n" ); } // true if ( [bank1 respondsToSelector: @selector( addAmount: )] == YES ) { printf( "bank1响应addAmount:函数\n" ); } // free memory [bank1 free]; [b free]; return 0; }
id类型可以接受各种类型的对象,然后调用对应的函数。调用函数时,Objective C在编译的时候并不会检查该对象是否有该函数,需要开发人员自己确保调用的有效。另外Objective C也提供功能,在运行时检查某对象是否具有某函数。
类的高级使用:继承、类别、扮演、协议
////////////// BankMath.h #import "Bank.h" @interface Bank(Math) //为类Bank定义一个类别Math -(void) add: (int) b; //Math中的函数add -(void) sub: (int) b; //Math中的函数sub @end @protocol Auditable //定义一个协议 -(void) audit; //其中包括一个函数audit的定义 @end @interface ExBank: Bank<Auditable> //ExBank类继承Bank,同时实现Auditable协议 -(void) print; //定义一个新的函数print,覆盖父类Bank中的print函数 @end ////////////// 实现部分 BankMath.m #import "BankMath.h" @implementation Bank (Math) //Bank的类别Math的实现部分 -(void) add: (int) f { amount ++; } -(void) sub: (int) f { amount --; } @end @implementation ExBank // 实现新定义的函数print -(void) print { printf("ExBank amount=%i", amount); } // 实现协议中包含的函数audit -(void) audit { printf("audit: amount=%i", amount); } @end ////////////// main.m #import <stdio.h> #import "Bank.h" int main( int argc, const char *argv[] ) { Bank *bank = [[Bank alloc] init]; [bank add: 10]; //直接使用Bank对象类别Math中的函数 [bank sub: 5]; //直接使用Bank对象类别Math中的函数 [bank print]; [ExBank poseAsClass: [Bank class]]; //使用ExBank来扮演Bank Bank *bank2 = [[Bank alloc] init]; //对Bank的调用,就是对ExBank的调用 [bank2 print]; //调用ExBank的print函数 [bank2 audit]; //调用ExBank的audit函数 id auditable = bank2; //为auditable赋值bank2 [auditable audit]; //调用bank2的函数audit //[auditable print]; //不行,因为Auditable类型中没有该函数 [bank free]; // 释放对象 [bank2 free]; // 释放对象 return 0; }
-
类定义@interface,相当于Java和C++中的class
-
继承,与Java继承类似,没有C++中继承的那么多繁琐的访问范围差别
-
类别(categories),是用来扩展类的好办法,比继承更方便,因为你不需要有源代码就可以扩充某个类。
-
扮演(Posting),可以在运行时指定用某个类A来替代另一个类B,这样此后所有对B的调用都是对A的调用。
-
协议(@protocol),相当于Java的接口,或C++的abstract class。定义在其中的函数只有定义而不需要实现。使用协议的时候,一个类可以实现多个协议,多个协议之间用逗号分隔列出。