从 C 到 Objective C 入门2

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。定义在其中的函数只有定义而不需要实现。使用协议的时候,一个类可以实现多个协议,多个协议之间用逗号分隔列出。
DeliciousDiggFacebookStumbleUponFriendFeedMySpaceTechnorati FavoritesTwitterLinkedInRedditGoogle BookmarksMixxShare

关于 Harry

关注产品管理,敏捷,Google,iPhone等领域。