初探Object-c 3 :多态,动态类型,动态绑定

先来看看自己写的一个例子,参考Objective-C 2.0程序设计

在上篇Fraction类的基础上,再新建了一个Complex类,作为一个虚数类。

//
//  Complex.h
//  MyProduct
//
//  Created by 陈思博 on 15/4/1.
//  Copyright (c) 2015年 陈思博. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Complex : NSObject
{

    double real;
    double imaginary;
}

@property double real,imaginary;

-(void) print;
-(void) setReal:(double) r andImaginary:(double) i;
-(Complex *) add:(Complex *) f;


@end
//
//  Complex.m
//  MyProduct
//
//  Created by 陈思博 on 15/4/1.
//  Copyright (c) 2015年 陈思博. All rights reserved.
//

#import "Complex.h"

@implementation Complex


@synthesize real,imaginary;

-(void) print
{
    NSLog(@"%g + %gi ",real , imaginary);
}

-(void) setReal:(double)r andImaginary:(double)i
{
    real = r;
    imaginary = i;
}

-(Complex *) add :(Complex *) f
{
    Complex *result =[[Complex alloc] init];

    [result setReal:f.real+real andImaginary:f.imaginary+imaginary];

    return result;
}

@end

测试类如下:

//
//  main.m
//  MyProduct
//
//  Created by 陈思博 on 15/4/1.
//  Copyright (c) 2015年 陈思博. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Fraction.h"
#import "Student.h"
#import "Complex.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...

        id Idvalue;

        Fraction * aFraction = [[Fraction alloc] init];
        Fraction * bFraction = [[Fraction alloc] init];

        [aFraction setTo:3 over:5];
        [bFraction setTo:1 over:9];

        [aFraction print];
        [bFraction print];

        NSLog(@"idvalue is ");

        Idvalue = [aFraction add:bFraction];

//        [[aFraction add:bFraction] print];
        [Idvalue print];

        Complex *aComplex = [[Complex alloc] init];
        Complex *bComplex = [[Complex alloc] init];

        [aComplex setReal:2 andImaginary:5];
        [bComplex setReal:5 andImaginary:8];

        Idvalue = [aComplex add:bComplex];
        NSLog(@"idvalue is ");

        [Idvalue print];
//        [[aComplex add:bComplex] print];

    }
    return 0;
}

输出 :

2015-04-01 16:35:40.482 MyProduct[2402:126700] 3/5
2015-04-01 16:35:40.484 MyProduct[2402:126700] 1/9
2015-04-01 16:35:40.484 MyProduct[2402:126700] idvalue is 
2015-04-01 16:35:40.485 MyProduct[2402:126700] 32/45
2015-04-01 16:35:40.485 MyProduct[2402:126700] idvalue is 
2015-04-01 16:35:40.485 MyProduct[2402:126700] 7 + 13i 
Program ended with exit code: 0

可以看到,id类型在接受不同类的赋值的时候,都可以作为一个具体的类的事例。

id类型是OC中的动态类型,可以被视为通用的对象类型。就是说id类型可以属于任何类的对象。在运行时,系统首先检查存储在dataValue中的对象类型,然后调用所属对象中的对应的方法。正如上面代码中idValue在属于不同类的对象时调用了不同类属的print方法。

使用id类型要注意的问题

虽然id类型非常灵活,但是不能大规模的使用在程序中。究其原因,是因为id类型只有在运行时才被检查类的所属。相对于静态的类型定义,如Complex *f,在编译的时候就接受检查,动态类型更容易报错而且不会被发现。

如果使用动态类型来调用一个方法,需要注意,如果在多个类中实现名称相同的方法,那每个方法都必须符合各个参数的类型和返回值类型。这样编译器才能为消息表达式生成正确的代码
—-来源书上

使用动态类型,有一些方法可以来对类型的所属类进行判断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值