zoukankan      html  css  js  c++  java
  • iOS开发之泛型使用

    1. 泛型:限制类型

    • 1.1.泛型使用场景:

      • 1.在集合(数组NSArray、字典NSDictionary、集合NSSet)中使用泛型比较常见。

      • 2.当声明一个类,但是类里面的某些属性的类型不确定的时候,我们才使用泛型。

    • 1.2.泛型书写规范

        在类型后面定义泛型:NSMutableArray<UITouch *> dataArray 

    • 1.3.泛型修饰

        只能修饰方法的调用。 

    • 1.4.泛型好处: 

        1.提高开发的规范,减少程序员之间的交流。

        2.通过集合取出来的对象,可以直接当做泛型对象使用。这样我们就可以直接使用.点语法。

    2.代码使用泛型:

    • 2.1.声明一个泛型为NSString的数组
      具体做法就是在 NSMutableArray 后带一个 <NSString *> ,尖括号内部即为泛型类型

      @property (nonatomic, strong, nullable) NSMutableArray<NSString *> *dataArray;
    • 2.2.当我们要给数组添加对象或取出对象的时候,系统就会自动提示应该传入或者取出来的对象的类型,这个类型就是你刚才声明的泛型类型
      • 没有使用泛型
        [self.dataArray addObject:<#(nonnull id)#>];
      • 使用泛型
         [self.dataArray addObject:<#(nonnull NSString *)#>];
      • 添加不正确的类型,会出现警告

         [self.dataArray addObject:@1];
      • 我们可以直接将集合中取出来的对象当做泛型使用

        NSInteger length = [self.dataArray.firstObject length];
      • 代码如下
         

    3.泛型的自定义

      刚才我们只是实现了系统类NSMutableArray的泛型。接下来我们要考虑下,我们怎么样在我们自己的类中声明一个泛型的属性呢?

      为了这个目的,我们创建一个 Language 的类表示 “语言”。并且创建两个 Language 的子类,分别叫 Java 和 IOS 。很明显这两个是“某一个类型的语言”。我们创建一个Person的类,给类声明一个泛型,在类的 .h 文件中声明一个声明一个属性,这个属性表示这个人会的语言,即为 IOS 或者 Java 。那么我们有以下两种声明方式:  

    • id:任何对象都能传进来
      @property (nonatomic, strong, null_unspecified) id language;
    •  Language:在外面调用的时候不能提示具体是哪种语言
      @property (nonatomic, strong, null_unspecified) Language *language;
    • 代码示例:
      #import "Language.h"
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface Person : Language
      /**! 第一种方式*/
      @property (nonatomic,strong,null_unspecified) id languageOne;
      /**! 第二种方式*/
      @property (nonatomic,strong,null_unspecified) Language *languageTwo;
      @end
      
      NS_ASSUME_NONNULL_END

      因为 Language 这个语言并不能代表这个 Person 究竟会什么语言,我们需要的属性时 IOS 和 Java。这两种都可以在调用的时候传入 Java 和 IOS 两种对象,但它们的缺点也非常明显,若使用 id 则我们可以传入任何对象,而不只是 Java 和 IOS ;使用 Language * 呢,我们没有办法在编译的时候确定这个人究竟会什么语言,而只能在运行时判断。有没有办法让我们在编译的时候就能知道 Person 具体会哪种 Language 呢?

      办法就是泛型。

      声明自定义类的泛型,我们需要做这样一步:

    • (给类)声明一个泛型
      @interface JTPerson<ObjectType> : NSObject

      看出区别了吗?我们在 interface 类名之后加了一对尖括号 <> ,中间是 ObjectType 。这个就代表泛型。这样我们在声明属性的时候就可以这么写: 

      @property (nonatomic, strong, null_unspecified) ObjectType language;

      也就是,我们现在不指定具体的类型,而在实例化这个类的时候确定这个泛型。若不确定,那么所有的 ObjectType 会自动变成 id 。
      像这样:

       // iOS
       JTPerson<IOS *> *iOSP = [[JTPerson alloc] init];
       // [iOSP setLanguage:@"123"];
       // [iOSP setLanguage:<#(IOS * _Null_unspecified)#>];
       // [iOSP setLanguage:[[Java alloc] init]];
       // Java
       JTPerson<Java *> *javaP = [[JTPerson alloc] init];
       // [javaP setLanguage:@"123"];
       // [javaP setLanguage:<#(Java * _Null_unspecified)#>];
       // [javaP setLanguage:[[IOS alloc] init]];

      这样,我们在声明 Person这个类的时候,就顺便声明了这个类的泛型。这样系统就会在你使用到泛型的属性与方法的时候,自动提醒你声明的泛型类型了。

       

    4. 泛型的协变与逆变 

      下图是系统 NSArray 的头文件部分,可以看到它使用了自定义泛型并命名为 OBjectType,

      在自定义泛型前加了一个 __covariant 的修饰符,这个修饰符就表示协变性


    • __covariant - 协变性,子类型可以强转到父类型(里氏替换原则)
    • __contravariant - 逆变性,父类型可以强转到子类型
  • 相关阅读:
    1094. Car Pooling
    121. Best Time to Buy and Sell Stock
    58. Length of Last Word
    510. Inorder Successor in BST II
    198. House Robber
    57. Insert Interval
    15. 3Sum java solutions
    79. Word Search java solutions
    80. Remove Duplicates from Sorted Array II java solutions
    34. Search for a Range java solutions
  • 原文地址:https://www.cnblogs.com/lxlx1798/p/11642938.html
Copyright © 2011-2022 走看看