1、id类型
// Complex.h==============================
#import <Foundation/Foundation.h>
@interface Complex : NSObject{
double real;
double imageinary;
}
-(Complex*) initWithReal:(double) r andImageinary:(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.h==============================
#import "Complex.h"
@implementation Complex
-(Complex*) initWithReal:(double) r andImageinary:(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{
NSLog(@"%f + %fi",real,imaginary);
}
@end
// main.m==============================
#import "Fraction.h"
#import "Complex.h"
int main(argc,const char * argv[]){
Fracion *frac = [[Fraction alloc] intiWithNumerator:3 andDenominator:5];
Complex *comp = [[Complex alloc] initWithReal:1.5 andImaginary:3.5];
id number = frac;
[number print];
number = comp;
[comp print];
[frc release];
[comp release];
return 0;
}
number先指向frac实例,调用了他的print方法,然后指向comp实例,调用了他的print
2、动态判断与选择器
假如别人传递给你一个id,你如何动态判断这个在运行时传递过来的对象到底有没有xxx方法那?
其实NSObject中有一系列这样的方法用于动态判断,类似java的反射机制
-(BOOL)isMemberOfClass:(Class) clazz //判断对象是否是clazz的实例,不包含子类的实例
-(BOOL)isKindOfClass:(Class) clazz //判断对象是否是clazz的实例或子类的实例
-(BOOL)respondsToSelector:(SEL) selector //判断类型或对象是否能够回应某个方法,这个方法使用选择器表示
+(BOOL)instancesRespondToSelector:(SEL) selector//判断类型所产生的实例是否能够回应某个方法,这个方法使用选择器表示
-(id)performSelector:(SEL) selector //用于动态调用类型或者对象上的一个方法
解释:
SEL类型,用于表示objc的一个方法
@selector(方法名) 例如:@selector(initWithWidth:andHeight:)不要丢掉冒号啊
Class id SEL 前不需要加星号
@import "MySquare.h"
int main(argc,const char * argv[]){
MyRectangle *rec = [[MyRectangle alloc] initWithWidth:2 andHeight:5];
[rec area];
MySquare *squa = [[MySquare alloc] initWithSize:6];
[squa area];
//判断对象是否是clazz的实例,不包含子类的实例
if([squa isMemberOfClass:[MyRectangle class]]){
NSLog(@"squa isMemberOfClass MyRectangle.");
}else{
NSLog(@"squa not isMemberOfClass MyRectangle.");
}
if([squa isKindOfClass:[MySquare class]]){
NSLog(@"squa isKindOfClass MySquare.");
}else{
NSLog(@"squa not isKindOfClass MySquare.");
}
//判断对象是否是clazz的实例或者子类的实例
if([squa isKindOfClass:[MyRectangle class]]){
NSLog(@"squa isKindOfClass MyRectangle.");
}else{
NSLog(@"squa not isKindOfClass MyRectangle.");
}
if([squa isKindOfClass:[MySquare class]]){
NSLog(@"squa isKindOfClass MySquare.");
}else{
NSLog(@"squa not isKindOfClass MySquare.");
}//判断对象或类型是否有能力回应指定方法
if([squa respondsToSelector:@selector(initWithSize:)]){
NSLog(@"YES");
}else{
NSLog(@"NO");
}
if([MySquare respondsToSelector:@selector(alloc)]){
NSLog(@"YES");
}else{
NSLog(@"NO");
}
if([rec respondsToSelector:@selector(initWithWidth:andHeight:)]){
NSLog(@"YES");
}else{
NSLog(@"NO");
}
//判断类产生的实例是否有能力回应指定的方法
if([MySquare instanceRespondsToSelector:@selector(initWithSize:)]){
NSLog(@"YES");
}else{
NSLog(@"NO");
}
if([MySquare instanceRespondsToSelector:@selector(alloc:)]){
NSLog(@"YES");
}else{
NSLog(@"NO");
}
//动态调用类或者对象上的一个方法
id x_id = [rec performSelector:@selector(area)];
[MyRectangle performSelector:@selector(alloc)];
[rec release];
[squa release];4、类别
想扩充一个类的功能,但有不想使用继承,就可以选择类别
写一个Fraction的类别,为Fraction类增加两个方法
//FractionMath.h=====================================
#import "Fraction.h"
@interface Fraction(Math1)
-(Fraction*)mul:(Fraction*)f;//乘法,就是传入一个Fraction作为参数,与当前Fraction进行计数
-(Fraction*)div:(Fraction*)f;//除法
@end
@interface Fraction(Math2)
-(Fraction*)add:(Fraction*)f;
@end
//FractionMath.m =======================================
#import "Fraction.h"
@implementation Fraction(Math1)
-(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]]
}
@end
@implementation Fraction(Math2)
-(Fraction*)add:(Fraction*)f{
return [[Fraction alloc] initWithNumerator:
numerator *[f denominator] + denominator*[f numerator]
denominator:denominator*[f denominator]];
}
@end
//main.m======================================
#import "FractionMath.h"
int main(int argc,const char *argv[]){
Fraction *frac1 = [[Fraction alloc] initWithNumerator:1 denominator:3];
Fraction *frac2 = [[Fraction alloc] initWithNumerator:2 denominator:5];
Fraction *frac3 = [[frac1 mul:frac2];
[frac1 print];
NSLog(@"*");
[frac2 print];
NSLog(@"=");
[frac3 print];
NSLog(@"\n");
Fration *frac5 = [frac1 add:frac2];
[frac2 print];
NSLog(@"+");
[frac2 print];
NSLog(@"=");
[frac2 print];
NSLog(@"\n");
[frac1 release];
[frac2 release];
[frac3 release];
[frac5 release];
return 0;
}
注意:
类别不可以声明新的实例变量,而且一旦你定义的方法与原始类中的方法名相同,那么原始方法将被隐藏起来
因为不是继承结构,你不能在类别中的方法使用super激活原始类的同名方法
类别还有一个功能,就是隐藏方法,我们在Fraction.m的最后增加如下方法
@interface Fraction(Math3)
-(Fraction*)sub:(Fraction*)f;//减法
@end
@implementation Fraction(Math3)
-(Fraction*)sub:(Fraction*)f{
return [[Fraction alloc] initWithNumerator:
numerator*[f denominator]-denominator*[f numerator]
denominator:denominator*[f denominator]];
}
@end
在。m文件中定义@interface?是的,因为@interface一旦定义在。m文件中,它就不能以header文件形式被导入到其他的类里了,
也就是这样的@interface中定义的方法相当于隐藏了,只有zhege。m编译单元内看见
}
本文介绍了Objective-C中的id类型应用、动态判断与选择器的使用、以及通过类别方式为已有类扩展功能的方法。通过具体代码示例展示了如何实现复数运算、分数运算等,并深入探讨了类别中方法的实现细节。
590

被折叠的 条评论
为什么被折叠?



