2019-02-13 iOS泛型ObjectType的协变__covariant和逆变__contravariant

二转:https://blog.csdn.net/imkata/article/details/78859482


一、泛型作用

    泛型:限制类型

    为什么要推出泛型?迎合swift

    泛型作用:

        1、限制类型;

        2、提高代码规划,减少沟通成本,一看就知道集合中是什么东西或者类隶属于什么父类型。

二、泛型用法:

    __covariant:协变,子类转父类;

    eg:

@interface MyPageViewController<__covariant ViewControllerType:UIViewController *> : MyBaseViewController

@interface MyKeyValues <__covariant KeyType,__covariant ObjectType> : NSObject

    __contravariant:逆变,父类转子类;

※个人理解:类似于基础数据类型大转小(__contravariant),小转大(__covariant)。

1、泛型声明:在声明类的时候,在类的后面<泛型名称>

// 第一步 声明泛型

@interface Person<__covariant ObjectType> : NSObject

// 语言

@property (nonatomic, strong) ObjectType language;

2、使用泛型 类型<限制类型>

// iOS

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

p.language = ios;

※不遵守泛型仅仅是报警告

三、泛型在开发中的使用

    泛型在开发中使用场景:

    1、用于限制集合类型

    泛型好处:

    1、从数组中取出来,可以使用点语法关联;

    2、给数组添加元素,有提示。

    @property (nonatomic, strong) NSMutableArray *arr;

    限制数据里面的集合是NSString类型。

    ※ id是不能使用点语法

    泛型注意点:

    在数组中,一般用可变数组添加方法,泛型才会生效;

    如果使用的不可变数组,添加元素,泛型没有效果。

四、泛型使用举例

    什么时候使用泛型?

    在声明类的时候,不确定某些属性或者方法类型,在使用这个类的时候才确定,就可以采用泛型。

    举例场景:自定义Person,会一些编程语言(iOS, Java),在声明Person,不确定这个人会什么,在使用Person才知道这个Person会什么语言。

    如果没有定义泛型,默认就是id类型。

(一)、先自定义类

1、自定义Person类。

里面有一个language属性,不知道是什么类型的,自定义为泛型,并且添加协变和逆变声明。

// Person.h

#import

// 第一步 声明泛型

// __covariant 协变,子类转父类  泛型名字是ObjectType

@interface Person<__covariant ObjectType> :NSObject

// 语言

@property (nonatomic, strong) ObjectType language;

@end

2、定义语言类Language

#import

@interface Language : NSObject

@end

3、定义语言子类Java语言

#import "Language.h"

@interface Java : Language

@end

4、定义语言子类iOS语言

#import "Language.h"

@interface iOS : Language

@end

(二)、下面介绍如何使用

1、首先是没有协变和逆变

#import

// 泛型名字是ObjectType

@interface Person : NSObject

// 语言

@property (nonatomic, strong) ObjectType language;

@end

- (void)test

{

    Java *java = [[Java alloc] init];

    iOS *ios = [[iOS alloc] init];


    // iOS  指定这个人会的是iOS

    Person *p = [[Personalloc] init];

    p.language = ios;


    // Java  指定这个人会的是Java

    Person *p1 = [[Personalloc] init];

    p1.language = java;

}

2、添加了协变

#import

// 第一步 声明泛型

// __covariant 子类转父类  泛型名字是ObjectType

@interface Person<__covariant ObjectType> : NSObject

// 语言

@property (nonatomic, strong) ObjectType language;

@end

// 子类转父类

- (void)covariant

{

    iOS *ios = [[iOS alloc] init];

    Language *language = [[Language alloc] init];

    // 只会iOS

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

    p.language = ios;


    // Language 都会

    Person *p1 = [[Person alloc] init];

    p1 = p;

    // ※如果没添加协变会报指针类型错误警告

}

3.添加了逆变

#import

//第一步 声明泛型

//__contravariant 可以逆变,父类转子类  泛型名字是ObjectType

@interface Person<__contravariant ObjectType> : NSObject

// 语言

@property (nonatomic, strong) ObjectType language;

@end

- (void)contravariant {

    //第二步 定义泛型

    iOS *ios = [[iOS alloc] init];

    Language *language = [[Language alloc] init];


    // 父类转子类  都会

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

    p.language = language;


    // 只会iOS

    Person *p1 = [[Person alloc] init];

    p1 = p; 

    // ※如果没添加逆变会报指针类型错误警告

}

你可能感兴趣的:(2019-02-13 iOS泛型ObjectType的协变__covariant和逆变__contravariant)