二转: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;
// ※如果没添加逆变会报指针类型错误警告
}