Object-C学习(四)

CSDN版 2011-07-14

引用:http://blog.csdn.net/huanglx1984/article/details/4299965

我们之前说到Objective-C是一种很好的面向对象的语言,和C++和Java相比,Objective-C有一些自己独特的东西,下面我们来简单的介绍一下。

1)Category

回想一下,在C++中,如果我们想继承一个类,给它添加一些新的功能,我们需要什么?当然是我们需要得到这个类的源代码。但是在Objective-C中,由于有了这个Category的概念,我们可以在没有源代码的情况下,为一个已经存在的类添加一些新的功能,比如:

//DisplayMath.h

@interfaceRectangle(Math)

-(int)calculateArea;

-(int)calculatePerimeter;

@end

//DisplayMath.m

@implementationRectangle(Math)

-(int)calculateArea{

returnwidth*height;

}

-(int)calculatePerimeter{

return2*(width+height)

}

@end

这里,使用了之前定义的Rectangle类,我们想为它添加两个功能:计算面积和周长。即使没有Rectangle类的源代码,我们也可以通过Category创建Rectangle的子类。

使用Category的时候,需要注意两个地方:

1)只能添加新的方法,不能添加新的数据成员

2)Category的名字必须是唯一的,比如这里,就不允许有第二个Math存在。

如何使用:

intmain(intargc,char*argv[]){

Rectangle*rect=[[Rectanglealloc]initWithWidth:5andHeight:10];

[rectcalculateArea];

[rectrelease];

}

2)如何创建私有方法

我们知道可以使用@private来声明私有变量,但是如何声明私有方法呢?

Objective-C中并没有什么关键词来修饰方法,如果我们想让某个方法不被其他的类所见,唯一的方法就是不让这个方法出现在头文件中。比如:

//MyClass.h

#import<Foundation/NSObject.h>

@implementationMyClass

-(void)sayHello;

@end

//MyClass.m

#import"MyClass.h"

@implementationMyClass

-(void)sayHello{

NSLog(@"Hello");

}

@end

@interfaceMyClass(Private)

-(void)kissGoodbye;

@end

@implementationMyClass(Private)

-(void)kissGoodbye{

NSLog(@"kissgoodbye");

}

@end

怎么样,看到了Category的应用么?是的,利用Category可以方便的实现“私有”方法。

3)Protocol

在Objective-C中,Protocol的概念很象Java中的interface或者C++中的virtualclass。

来看下面这个例子:

@protocolPrinting

-(void)print;

@end

//MyDate.h

@interfaceMyDate:NSObject<Printing>{

intyear,month,day;

}

-(void)setDateWithYear:(int)yandMonth:(int)mandDay:(int)d;

@end

//MyDate.m

#import<stdio.h>

#import"MyDate.h"

@implementationMyDate

-(void)setDateWithYear:(int)yandMonth:(int)mandDay:(int)d{

year=y;

month=m;

day=d;

}

-(void)print{

printf("%4d-%2d-%2d",year,month,day);

}

@end

我们首先声明了Printing协议,任何遵守这个协议的类,都必须实现print方法。在ObjectiveC中,我们通过<>来表示遵守某个协议。当某个类声明要遵守某个协议之后,它就必须在.m文件中实现这个协议中的所有方法。

如何使用:

intmain(intargc,char*argv[]){

MyDate*dat=[[MyDatealloc]init];

[datinitDateWithYear:1998andMonth:09andDay:01];

id<Printing>var=dat;

[varprint];

if([datconformsToProtocol:@protocol(Printing)]==YES){}//true

[datrelease];

}

注意两个地方:1)使用id<Printing>作为类型,而不是象C++中,使用Printing*var;2)conformsToProtocol类似于之前所说的respondsToSelector,用于动态检查某个对象是否遵守某个协议。

相关推荐