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

分数类

#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/30
2015-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/30
2015-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/30
2015-03-20 13:09:46.032 Meature[549:303] 13+5.7i
2015-03-20 13:09:46.033 Meature[549:303] 1/3
2015-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/3
2015-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] Fraction
2015-03-20 17:05:15.635 TTTTTT[1098:303] Fraction
2015-03-20 17:05:15.636 TTTTTT[1098:303] Complex
2015-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] YES
2015-03-20 18:59:30.451 Rectangle[1194:303] NO
2015-03-20 18:59:30.453 Rectangle[1194:303] NO
2015-03-20 18:59:30.453 Rectangle[1194:303] YES
2015-03-20 18:59:30.454 Rectangle[1194:303] YES
2015-03-20 18:59:30.455 Rectangle[1194:303] YES
2015-03-20 18:59:30.456 Rectangle[1194:303] YES
2015-03-20 18:59:30.456 Rectangle[1194:303] YES
2015-03-20 18:59:30.457 Rectangle[1194:303] YES
2015-03-20 18:59:30.458 Rectangle[1194:303] YES
2015-03-20 18:59:30.458 Rectangle[1194:303] YES
2015-03-20 18:59:30.459 Rectangle[1194:303] YES
2015-03-20 18:59:30.459 Rectangle[1194:303] YES
接受者为类的方法之中 类也可以通过class方法来获取[squa class]或[Square class]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值