很多小伙伴都仅仅知道泛型是限制类型的,其他的就不太清楚了,下面给大家详细讲解一下泛型,以及协变和逆变。
泛型作用:
1.限制类型;
2.提高代码规划,减少沟通成本,一看就知道集合中是什么东西。
泛型声明:在声明类的时候,在类的后面<泛型名称>
泛型定义用法:类型<限制类型>
泛型好处:
1.从数组中取出来,可以使用点语法;
2.给数组添加元素,有提示。
很多人会疑惑,为什么集合可以直接使用泛型?而我们自定义的类中却不能使用泛型,因为,集合已经声明过泛型了,我们可以直接定义使用,可是我们自定义的类却并没有声明泛型。
@interface NSMutableArray<ObjectType>: NSArray<ObjectType>
ObjectType就是泛型的名字,我们可以直接定义使用
@property (nonatomic, strong) NSMutableArray<NSString *>*arr;
注意:在声明中,泛型的名字ObjectType是可以任意取得,当我们在定义泛型的类型是NSString *的时候,ObjectType就会默认成NSString *。
下面给大家讲解一下如何自定义泛型:
自定义Person类和IOS类
声明泛型
#import<Foundation/Foundation.h>
@interface Person<ObjectType>: NSObject
//语言
@property (nonatomic, strong) ObjectType language;
@end
定义泛型
IOS *ios = [[IOS alloc] init];
Person*p = [[Person alloc] init];
p.language = ios;
协变,逆变用于父子类型转换
__covariant:协变 子类转父类
__contravariant:逆变 父类转子类
自定义Person类,Language类和IOS类,IOS类继承自Language类
协变:
子类转父类
#import
@interface Person<__covariant ObjectType>: NSObject
//语言
@property (nonatomic, strong) ObjectType language;
@end
IOS *ios = [[IOS alloc] init];
//iOS
Person<IOS *>*p = [[Person alloc] init];
p.language = ios;
//Language
Person<Language *>*p1 = [[Person alloc] init];
p1 = p;
逆变
父类转子类
#import
@interface Person<__contravariant ObjectType>: NSObject
//语言
@property (nonatomic, strong) ObjectType language;
@end
Language *language = [[Language alloc] init];
//Language
Person*p = [[Person alloc] init];
p.language = language;
//iOS
Person*p1 = [[Person alloc] init];
p1 = p;