动态类型调用方法的参数和返回值

来源:互联网 发布:无乃后乎句式 编辑:程序博客网 时间:2024/06/05 20:48

分数类

#import <Foundation/Foundation.h>@interface Fraction : NSObject@property int numerator,denominator;-(void) print;-(double) convertToNum;-(void) setNumerator:(int)n andDenominator:(int)d;-(Fraction *) add:(Fraction *)f;-(Fraction *) sub:(Fraction *)f;-(Fraction *) mul:(Fraction *)f;-(Fraction *) div:(Fraction *)f;-(void) reduce;@end
#import "Fraction.h"@implementation Fraction@synthesize numerator,denominator;-(void) print;{    NSLog(@"%i/%i",self.numerator,self.denominator);}-(double) convertToNum{    if (self.denominator!=0) {        return (double)self.numerator/self.denominator;    }    else        return NAN;}-(void) setNumerator:(int)n andDenominator:(int)d{    self.numerator=n;    self.denominator=d;}-(Fraction *) add:(Fraction *)f{    Fraction *result=[[Fraction alloc] init];    result.numerator=self.numerator*f.denominator+self.denominator*f.numerator;    result.denominator=self.denominator*f.denominator;    [result reduce];    return result;}-(Fraction *) sub:(Fraction *)f{    Fraction *result=[[Fraction alloc] init];    result.numerator=self.numerator*f.denominator-self.denominator*f.numerator;    result.denominator=self.denominator*f.denominator;    [result reduce];    return result;}-(Fraction *) mul:(Fraction *)f{    Fraction *result=[[Fraction alloc] init];    result.numerator=self.numerator*f.numerator;    result.denominator=self.denominator*f.denominator;    [result reduce];    return result;}-(Fraction *) div:(Fraction *)f{    Fraction *result=[[Fraction alloc] init];    result.numerator=self.numerator*f.denominator;    result.denominator=self.denominator*f.numerator;    [result reduce];    return result;}-(void) reduce{    int u,v,temp;    u=self.numerator;    v=self.denominator;    while (v!=0) {        temp=u%v;        u=v;        v=temp;    }    self.numerator/=u;    self.denominator/=u;}@end
复数类

#import <Foundation/Foundation.h>@interface Complex : NSObject@property double real,imaginary;-(void) print;-(void) setReal:(double)r andImaginary:(double)i;-(Complex *) add:(Complex *)c;-(Complex *) sub:(Complex *)c;-(Complex *) mul:(Complex *)c;-(Complex *) div:(Complex *)c;@end
#import "Complex.h"@implementation Complex@synthesize real,imaginary;-(void) print{    NSLog(@"%g+%gi",self.real,self.imaginary);}-(void) setReal:(double)r andImaginary:(double)i{    self.real=r;    self.imaginary=i;}-(Complex *) add:(Complex *)c{    Complex *result=[[Complex alloc] init];    result.real=self.real+c.real;    result.imaginary=self.imaginary+c.imaginary;    return result;}-(Complex *) sub:(Complex *)c{    Complex *result=[[Complex alloc] init];    result.real=self.real-c.real;    result.imaginary=self.imaginary-c.imaginary;    return result;}-(Complex *) mul:(Complex *)c{    Complex *result=[[Complex alloc] init];    result.real=self.real*c.real;    result.imaginary=self.imaginary*c.imaginary;    return result;}-(Complex *) div:(Complex *)c{    Complex *result=[[Complex alloc] init];    result.real=self.real/c.real;    result.imaginary=self.imaginary/c.imaginary;    return result;}@end
多态
不同的类可以定义同名的方法 如下
        Fraction *f1=[[Fraction alloc] init];        Fraction *f2=[[Fraction alloc] init];        Fraction *f3;        Complex *c1=[[Complex alloc] init];        Complex *c2=[[Complex alloc] init];        Complex *c3;        [f1 setNumerator:1 andDenominator:10];        [f2 setNumerator:2 andDenominator:15];        [c1 setReal:18 andImaginary:2.5];        [c2 setReal:-5 andImaginary:3.2];        f3=[f1 add:f2];        c3=[c1 add:c2];        [f3 print];        [c3 print];
2015-03-20 13:12:48.074 TTTTTT[585:303] 7/302015-03-20 13:12:48.076 TTTTTT[585:303] 13+5.7i
Fraction类和Complex类都有add方法和print方法 根据对象所属的类 调用相对应的方法
动态类型(即id类型)
id类型其实就是一个指针 该指针可以存放任何类的对象
动态绑定
动态绑定其实质是 声明为id类型的对象 在编译时无法确定究竟存放了哪个类的对象 直到程序运行时才确定 还是那句话 根据id对象存放的对象所属的类 动态调用相对应的方法 如下
        id result;        result=[f1 add:f2];        [result print];        result=[c1 add:c2];        [result print];
2015-03-20 13:12:48.078 TTTTTT[585:303] 7/302015-03-20 13:12:48.079 TTTTTT[585:303] 13+5.7i
动态类型调用方法需要注意一下几点
1、如果在多个类中具有同名方法 方法与方法之间的参数类型必须保持一致 返回值也必须保持一致性 一致性指的是 int对int double对double 指针对指针 否则编译器会报错 比如加入Calculator类 Calculator类中的add:方法-(double) add:(double)value与上面两个类的add:方法在参数和返回值上没有保持一致
2、在保持一致性的前提下 如果参数是静态类型 编译器仍旧会发出警告 因为编译器只认最先进入的那个头文件中的add:方法 如下
#import "Fraction.h"#import "Complex.h"
        id resultFraction,resultComplex,result;        resultFraction=[f1 add:f2];        resultComplex=[c1 add:c2];        [resultFraction print];        [resultComplex print];                resultFraction=[resultFraction add:f1];        resultComplex=[resultComplex add:c1];        [resultFraction print];        [resultComplex print];
2015-03-20 13:09:46.029 Meature[549:303] 7/302015-03-20 13:09:46.032 Meature[549:303] 13+5.7i2015-03-20 13:09:46.033 Meature[549:303] 1/32015-03-20 13:09:46.034 Meature[549:303] 31+8.2i
最先进入的是Fraction头文件 所以编译器在遇到[resultComplex add:c1]会发出警告 表示不兼容的指针类型 Complex类型送入到Fraction类型参数之中 其实这里没有任何问题
3、如果参数也是id类型 那么编译器就不会发出警告 因为编译器不知道送入的指针类型 如下
        result=[resultFraction add:resultFraction];        [result print];        result=[resultComplex add:resultComplex];        [result print];
2015-03-20 13:09:46.034 Meature[549:303] 2/32015-03-20 13:09:46.035 Meature[549:303] 62+16.4i
关于类的问题
[对象 class]
获取当前对象的类对象 既可用于实例对象 也可用于类对象 如下
        Class c=[f1 class];        NSLog(@"%@",c);        c=[Fraction class];        NSLog(@"%@",c);        NSLog(@"%@",[c1 class]);        NSLog(@"%@",[Complex class]);
2015-03-20 17:05:15.634 TTTTTT[1098:303] Fraction2015-03-20 17:05:15.635 TTTTTT[1098:303] Fraction2015-03-20 17:05:15.636 TTTTTT[1098:303] Complex2015-03-20 17:05:15.637 TTTTTT[1098:303] Complex
@selector(方法)
既可用于实例方法 也可用于类方法 如下
        SEL s=@selector(setNumerator:andDenominator:);        NSLog(@"%@",NSStringFromSelector(s));        NSLog(@"%@",NSStringFromSelector(@selector(setReal:andImaginary:)));
2015-03-20 17:05:15.639 TTTTTT[1098:303] setNumerator:andDenominator:2015-03-20 17:05:15.640 TTTTTT[1098:303] setReal:andImaginary:
-(BOOL) isMemberOfClass:classObj 是否是classObj类的实例
-(BOOL) isKindOfClass:classObj 是否是classObj类或其子类的实例
+(BOOL) isSubclassOfClass:classObj 是否是classObj类的子类
+-(BOOL) respondsToSelector:selector 对象是否可以响应selector方法
+(BOOL) instancesRespondToSelector:selector 类的实例是否可以响应selector方法
其中respondsToSelector:既是实例方法又是类方法
方法包括从父类继承的方法
        Square *squa=[[Square alloc] init];        NSLog(@"%@",[squa isMemberOfClass:[Square class]]?@"YES":@"NO");        NSLog(@"%@",[squa isMemberOfClass:[Rectangle class]]?@"YES":@"NO");        NSLog(@"%@",[squa isMemberOfClass:[NSObject class]]?@"YES":@"NO");        NSLog(@"%@",[squa isKindOfClass:[Square class]]?@"YES":@"NO");        NSLog(@"%@",[squa isKindOfClass:[Rectangle class]]?@"YES":@"NO");        NSLog(@"%@",[squa isKindOfClass:[NSObject class]]?@"YES":@"NO");        NSLog(@"%@",[Square isSubclassOfClass:[Rectangle class]]?@"YES":@"NO");        NSLog(@"%@",[Square isSubclassOfClass:[NSObject class]]?@"YES":@"NO");        NSLog(@"%@",[squa respondsToSelector:@selector(setSide:)]?@"YES":@"NO");        NSLog(@"%@",[squa respondsToSelector:@selector(setWidth:andHeight:)]?@"YES":@"NO");        NSLog(@"%@",[Square respondsToSelector:@selector(alloc)]?@"YES":@"NO");        NSLog(@"%@",[Square instancesRespondToSelector:@selector(setSide:)]?@"YES":@"NO");        NSLog(@"%@",[Square instancesRespondToSelector:@selector(setWidth:andHeight:)]?@"YES":@"NO");
2015-03-20 18:59:30.450 Rectangle[1194:303] YES2015-03-20 18:59:30.451 Rectangle[1194:303] NO2015-03-20 18:59:30.453 Rectangle[1194:303] NO2015-03-20 18:59:30.453 Rectangle[1194:303] YES2015-03-20 18:59:30.454 Rectangle[1194:303] YES2015-03-20 18:59:30.455 Rectangle[1194:303] YES2015-03-20 18:59:30.456 Rectangle[1194:303] YES2015-03-20 18:59:30.456 Rectangle[1194:303] YES2015-03-20 18:59:30.457 Rectangle[1194:303] YES2015-03-20 18:59:30.458 Rectangle[1194:303] YES2015-03-20 18:59:30.458 Rectangle[1194:303] YES2015-03-20 18:59:30.459 Rectangle[1194:303] YES2015-03-20 18:59:30.459 Rectangle[1194:303] YES
接受者为类的方法之中 类也可以通过class方法来获取[squa class]或[Square class]
0 0
原创粉丝点击