泛型在开发中的应用

泛型在开发中的应用

一、什么是泛型?

泛型将接口的概念进一步延伸,“泛型”的字面意思就是广泛的类型。类、接口和方法代码可以应用于非常广泛的类型,代码与它们能够操作的数据类型不再绑定在一起,同一套代码可以用于多种数据类型,这样不仅可以复用代码,降低耦合性,而且还提高了代码的可读性以及安全性。

二、泛型的用法

1)泛型的类型

__covariant:协变, 子类转父类
__contravariant:逆变,父类转子类

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

 //声明泛型
 @interface Person<__covariant ObjectType> : NSObject
 // 语言
 @property (nonatomic, strong) ObjectType language;

3)使用泛型 类型<限制类型>

 Person<Chinese *> *p = [[Person alloc] init];
 p.language = chinese;

注:不遵守泛型仅仅是报警告

三、泛型在开发中的使用

泛型使用场景:用于限制集合类型或某些属性到创建的时候才能确定,如Foundation框架中的NSArray就使用了泛型:

@property (nonatomic, strong)NSMutableArray<NSString *> *arr;  //限制数据里面的集合是NSString类型

这样会在开发的过程中提供便利:1、从数组中取出来,可以使用点语法 2、给数组添加元素,有提示,同时可以避免添加错误类型。

注:在数组中,一般用可变数组添加方法,泛型才会生效;如果使用不可变数组添加元素,泛型没有效果(id类型不能使用点语法)。

四、泛型举例

自定义一个Person类,并且定义说的语言属性(Chinese,English);再声明Person,场景是不确定这个人会什么,在使用Person才知道这个Person会说什么语言。

1)运用泛型定义一些类

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

//Person.h
#import <Foundation/Foundation.h>
//声明泛型
//__covariant 协变,子类转父类   泛型名字是ObjectType
@interface Person<__covariant ObjectType> :NSObject
//语言
@property (nonatomic, strong) ObjectType language;
@end

定义一些语言类:

//Language
#import <Foundation/Foundation.h>
@interface Language : NSObject
@end
//Chinese
#import "Language.h"
@interface Chinese : Language
@end
//English 
#import "Language.h"
@interface English : Language
@end

2)定义好了之后,下面介绍如何使用

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

#import <Foundation/Foundation.h>
//泛型名字是ObjectType
@interface Person<ObjectType> : NSObject
//语言
@property (nonatomic, strong) ObjectType language;
@end
- (void)test
{
    Chinese *chinese = [[Chinese alloc] init];
    English *english = [[English alloc] init];
    
    // Chinese指定这个人会说的是chinese
    Person<Chinese *> *p = [[Person alloc] init];
    p.language = chinese;
    
    // English指定这个人会说的是english
    Person<English *> *p1 = [[Person alloc] init];
    p1.language = english;
}

2、添加了协变

#import <Foundation/Foundation.h>
//第一步 声明泛型
//__covariant 子类转父类   泛型名字是ObjectType
@interface Person<__covariant ObjectType> : NSObject
// 语言
@property (nonatomic, strong) ObjectType language;
@end

// 子类转父类
- (void)covariant
{
    Chinese *chinese = [[Chinese alloc] init];
    Language *language = [[Language alloc] init];
    // Chinese 只会说chinese
    Person<Chinese *> *p = [[Person alloc] init];
    p.language = chinese;
    
    // 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 {
    //第二步 定义泛型
    Chinese *chinese = [[Chinese alloc] init];
    Language *language = [[Language alloc] init];
    
    // 父类转子类都会
    Person<Language *> *p = [[Person alloc] init];
    p.language = language;
    
    // Chinese只会说iOS
    Person<Chinese *> *p1 = [[Person alloc]init];
    p1 = p; //如果没添加逆变会报指针类型错误警告
}

五、结语

泛型是编程语言设计的很好的特性,可以有助于提高代码的规范程度与易读性,所以还是建议开发者们可以在编程中适当的时候多用泛型来实现。

发布了74 篇原创文章 · 获赞 34 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/TuGeLe/article/details/105191121