OC中id数据类型的使用

动态数据类型id:
数据类型常用的有:
1.int整型;
2.double双精度型;
3.float单精度型;
4.char字符类型;
等......
数据类型的用途是什么呢?
    在计算机语言中,数据类型有三种用途,
1.定义变量;
2.作为函数的参数;
3.作为函数的返回值.
默认情况下,所有的数据类型都是静态数据类型.
默认数据类型的特点如下:
在编译时就知道变量的类型,知道变量中有哪些属性和方法,在编译的时候就可以访问这些属性和方法,并且如果通过静态数据类型定义变量,如果访问了不属于静态数据类型的属性和方法,那么编译器就会报错;
id也是一种数据类型,并且是一种动态数据类型,那么id和其他数据类型一样,也有同样的作用;
动态数据类型的特点:
在编译的时候编译器并不知道变量的真实类型,只有在运行的时候才知道真实的数据类型,并且如果通过动态数据类型定义变量,如果访问了不属于动态数据类型的属性和方法,编译器不会报错.
在多态中,通过静态数据类型定义变量,不能调用子类特有的方法;
  Animal * dog = [[Dog alloc]init];//使用父类接收子类的实例对象;

 Dog * dd = (Dog *)dog;//强制转换为子类类型

  [dd kanMen];//只有强制转换后才能调用子类特有的方法


在多态中,通过动态数据类型定义变量,可以调用子类特有的方法;

 id dog = [[Dog alloc]init];//创建一条狗;

  [dog kanMen];//这条狗可以直接调用Dog类具有的特有方法;

  [dog test];//这条狗还可以调用Dog私有的方法//只有实现没有生命的方法是私有方法;


在多态中,通过动态数据类型定义的变量,可以调用私有的方法
  
 Animal * dog = [[Dog alloc]init];//使用父类接收子类的实例对象;

 Dog * dd = (Dog *)dog;//强制转换为子类类型

  [dd test];//不能调用子类的私有方法

在多态中,如果父类有私有方法,只能在本类的方法中调用,如果子类中有父类私有方法的方法声明,则子类的对象可以直接调用父类的私有方法;(说明,OC中没有真正的私有方法,通过某种途径,父类也是可以调用其私有方法.)

id也存在弊端,由于动态数据类型可以调用任意方法, 所以有可能调用到不属于自己的方法, 而编译时又不会报错, 所以可能导致运行时的错误;

为了避免动态数据类型引发的运行时的错误, 一般情况下如果使用动态数据类型定义一个变量, 在调用这个变量的方法之前会进行一次判断, 判断当前变量是否能够调用这个方法;

if ([dog isKindOfClass:[Dog class]]) {

        //isKindOfClass , 判断指定的对象是否是某一个类, 或者是某一个类的子类

        [dog eat];

    }

//-------------------------------------------------------------------------------------------------------------

if ([dog isMemberOfClass:[Dog class]]) {

        // isMemberOfClass : 判断指定的对象是否是当前指定的类的实例

        [dog eat];

    }

id的应用场景: 多态, 可以减少代码量, 避免调用子类特有的方法需要强制类型转换

注释:
多态的条件:
     1.有继承关系
2.父类指向子类
       3.子类重写父类方法;

#import <Foundation/Foundation.h>

@interface Animal : NSObject

-(void)eat;

@implementation Animal

-(void)eat

{

    NSLog(@"吃饭");

}

-(void)test2

{

    NSLog(@"Animal私有方法test2");

}

@end

//———————————————————————//

@interface Dog : Animal

-(void)eat;

-(void)kanMen;

-(void)test2;

@end

@implementation Dog

-(void)eat

{

    NSLog(@"dog吃肉");

}

-(void)kanMen

{

    NSLog(@"汪汪叫");

}


-(void)test

{

    NSLog(@"私有方法test");

}

@end

//——————————————————————//

@interface Person : NSObject

-(void)eat:(Animal*)an;

@end

@implementation Person

-(void)eat:(Animal *)an

{

    [an eat];

}

@end

//———————————————————————//

int main(int argc, const char * argv[]) {

//    Animal *dog = [[Dog alloc]init];

//    [dog eat];


    //多态情况下,如果需要调用子类的特有属性,需要强制装换为子类类型

//    Animal * dog = [[Dog alloc]init];

//    Dog * dd = (Dog *)dog;

//    [dd kanMen];

//    [dd test];

    

    //使用id类型,在调用子类特有方法的时候,不用再强制转换,可以直接调用;

    //使用id类型,可以调用子类的私有方法;

    id dog = [[Dog alloc]init];

//    [dog kanMen];

//    [dog test];

    

    [dog test2];//



    

// 为了避免动态数据类型引发的运行时的错误一般情况下如果使用动态数据类型定义一个变量在调用这个变量的方法之前会进行一次判断判断当前变量是否能够调用这个方法

//    id dog2 = [[Dog alloc]init];

//    if ([dog2 isMemberOfClass:[Dog class]] ) {

//        [dog2 eat];

//    }

//  



//    Animal * an = [[Animal alloc]init]; 

//    Dog * dog = [[Dog alloc]init];  

//    Person * p = [[Person alloc]init];


//    [p eat:dog];

  

    //真正意义的面向对象;只剩下具体的对象,

    //这里是又创建了一个人,和分别创建了一条狗和一只猫,然后就是人去喂猫和狗;

    


return 0;

 }

发布了123 篇原创文章 · 获赞 11 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览