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<iOS *> *p = [[Person alloc] init];

p.language = ios;

※不遵守泛型僅僅是報警告

三、泛型在開發中的使用

? ? 泛型在開發中使用場景:

????1、用于限制集合類型

? ? 泛型好處:

????1、從數組中取出來,可以使用點語法關聯;

????2、給數組添加元素,有提示。

????@property (nonatomic, strong) NSMutableArray<NSString *> *arr;

????限制數據里面的集合是NSString類型。

? ? ※ id是不能使用點語法

? ? 泛型注意點:

????在數組中,一般用可變數組添加方法,泛型才會生效;

????如果使用的不可變數組,添加元素,泛型沒有效果。

四、泛型使用舉例

? ? 什么時候使用泛型?

????在聲明類的時候,不確定某些屬性或者方法類型,在使用這個類的時候才確定,就可以采用泛型。

? ? 舉例場景:自定義Person,會一些編程語言(iOS, Java),在聲明Person,不確定這個人會什么,在使用Person才知道這個Person會什么語言。

? ? 如果沒有定義泛型,默認就是id類型。

(一)、先自定義類

1、自定義Person類。

里面有一個language屬性,不知道是什么類型的,自定義為泛型,并且添加協變和逆變聲明。

// Person.h

#import <Foundation/Foundation.h>

// 第一步 聲明泛型

// __covariant 協變,子類轉父類? 泛型名字是ObjectType

@interface Person<__covariant ObjectType> :NSObject

// 語言

@property (nonatomic, strong) ObjectType language;

@end

2、定義語言類Language

#import <Foundation/Foundation.h>

@interface Language : NSObject

@end

3、定義語言子類Java語言

#import "Language.h"

@interface Java : Language

@end

4、定義語言子類iOS語言

#import "Language.h"

@interface iOS : Language

@end

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

1、首先是沒有協變和逆變

#import <Foundation/Foundation.h>

// 泛型名字是ObjectType

@interface Person<ObjectType> : NSObject

// 語言

@property (nonatomic, strong) ObjectType language;

@end

- (void)test

{

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

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


? ? // iOS? 指定這個人會的是iOS

? ? Person<iOS *> *p = [[Personalloc] init];

? ? p.language = ios;


? ? // Java? 指定這個人會的是Java

? ? Person<Java *> *p1 = [[Personalloc] init];

? ? p1.language = java;

}

2、添加了協變

#import <Foundation/Foundation.h>

// 第一步 聲明泛型

// __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<iOS *> *p = [[Person alloc] init];

? ? p.language = ios;


? ? // Language 都會

? ? Person<Language *> *p1 = [[Person alloc] init];

? ? p1 = p;

????// ※如果沒添加協變會報指針類型錯誤警告

}

3.添加了逆變

#import <Foundation/Foundation.h>

//第一步 聲明泛型

//__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<Language *> *p = [[Person alloc] init];

? ? p.language = language;


? ? // 只會iOS

? ? Person<iOS *> *p1 = [[Person alloc] init];

? ? p1 = p;?

????// ※如果沒添加逆變會報指針類型錯誤警告

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。