泛型使用场景:
- 在集合(数组、字典、NSSet)中使用泛型比较常见。
- 当声明一个类,类里面的某些属性的类型不确定,这时候我们才使用泛型。
泛型书写规范
在类型后面定义泛型,比如如下所示:
NSMutableArray<UITouch *> *datas
泛型好处:
- 提高开发规范,减少程序员之间交流
- 通过集合取出来对象,直接当做泛型对象使用,可以直接使用点语法。
纯白的讲:
- __covariant(协变):用于泛型数据强转类型,可以向上强转,子类可以转成父类。
- __contravariant(逆变):用于泛型数据强转类型,可以向下强转,父类可以转成子类。
例如:
// __covariant 协变,子类转父类;泛型名字是ObjectType
@interface Person<__covariant ObjectType> :NSObject
// 语言
@property (nonatomic, strong) ObjectType language;
@end
@interface Language : NSObject
@end
@interface Java : Language
@end
@interface Objective_C : Language
@end
首先是没有添加协变和逆变
@interface Person<ObjectType> : NSObject
// 语言
@property (nonatomic, strong) ObjectType language;
@end
- (void)test {
Java *java = [[Java alloc]init];
Objective_C *ios = [[Objective_C alloc]init];
// iOS 指定这个人会的是iOS
Person<Objective_C *> *p = [[Person alloc]init];
p.language = ios;
// Java 指定这个人会的是Java
Person<Java *> *p1 = [[Person alloc]init];
p1.language = java;
}
添加了协变
// __covariant 子类转父类;泛型名字是ObjectType
@interface Person<__covariant ObjectType> : NSObject
// 语言
@property (nonatomic, strong) ObjectType language;
@end
// 子类转父类
- (void)covariant {
Objective_C *ios = [[Objective_C alloc]init];
Language *language = [[Language alloc]init];
// iOS 只会iOS
Person<Objective_C *> *p = [[Person alloc]init];
p.language = ios;
// Language 都会
Person<Language *> *p1 = [[Person alloc]init];
p1 = p;
// 如果没添加协变会报指针类型错误警告
}
添加了逆变
// __contravariant 可以逆变,父类转子类 泛型名字是ObjectType
@interface Person<__contravariant ObjectType> : NSObject
// 语言
@property (nonatomic, strong) ObjectType language;
@end
- (void)contravariant {
// 第二步 定义泛型
Objective_C *ios = [[Objective_C alloc]init];
Language *language = [[Language alloc]init];
// 父类转子类 都会
Person<Language *> *p = [[Person alloc]init];
p.language = language;
// iOS 只会iOS
Person<Objective_C *> *p1 = [[Person alloc]init];
p1 = p;
// 如果没添加逆变会报指针类型错误警告
}
网友评论