0%

Dart学习笔记 (八)

泛型 , 泛型方法 , 泛型类 , 泛型接口

泛型

泛型方法

  • 通俗的理解:泛型就是解决,接口,方法重用性,以及对不特定数据类型的支持(对不特定数据类型的数据校验)

  • 如果我们想要自定义一个方法,他传入的数据类型是什么那么返回的也是什么类型的话可以这么写 例如:

    1
    2
    3
    4
    5
    6
    String getData(String value){
    return value;
    }
    int getData(int value){
    return value;
    }

    但这么写的话你想传入String返回String就必须写一个方法,如果你又需要传入int再返回int的话就需要再写一个方法,会造成方法的冗(rong)余,当然我们可以在自定义方法的时候不给他指定类型,这样的话它就会传入什么类型返回什么类型但是这样同时也就放弃了自定义方法的类型校验,例如:

    1
    2
    3
    4
    getData(value){
    return 'xxx';
    }
    //这种情况下如果你调用时传入 int类型的123,返回的却是String类型的XXX
  • 想要同时满足传入什么类型返回什么类型和只能传入什么类型的类型校验的话,可以使用泛型方法

    例1:如何定义泛型方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    T getData<T>(T value){       //第一个T为定义泛型,定义泛型可以是任何大写字母但一般我们用T,第一个T表示返回类型校验
    return value; //另外两个T表示传入数据校验
    }
    print(getData<String>('你好'));//在调用时添加书名号,填入想要设置的传入返回类型 输出: 你好
    ----------------------------------------
    T getData<T>(T value){
    return value;
    }
    print(getData<int>(666)); //输出: 666

    例2:只对传入的参数进行校验,不对返回的类型进行校验

    1
    2
    3
    getDate<T>(T value){
    return value;
    }

泛型类

  • 泛型类同泛型方法的功能一致,List就是一个语言自带的泛型类(List定义数组的两种方式 例2)

  • 自定义泛型类和自定义泛型方法一样

    例1:非泛型,在一个自定义类里定义一个指定类型的List并循环遍历

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class Printclass{
    List list=List<String>(); //指定List传入内容为String类型
    void add(String value){ //没有返回值的自定义add方法,指定传入类型为String,
    list.add(value); //吧传入内容list.add进数组中
    }
    void printInfo(){
    list.forEach((value){ //自定义方法中用forEach循环遍历list
    print(value);
    });
    }
    }
    main(){
    Printclass p=Printclass();
    p.add('张三'); //调用add方法传入数据
    p.add('李四');
    p.add('王五');
    p.printInfo(); //调用printInfo方法循环遍历 输出: 张三 李四 王五
    }

    例2: 使用泛型类方法使其指定不特定数据类型校验,把例1中的案例改成泛型类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class Printclass<T>{
    List list=List<T>();
    void add(T value){
    list.add(value);
    }
    void printInfo(){
    list.forEach((value){
    print(value);
    });
    }
    }
    main(){
    Printclass p=Printclass<String>();
    p.add('张三');
    p.add('李四');
    p.add('王五');
    p.printInfo();
    }

泛型接口

  • 定义泛型接口的方法和泛型类相同

    例1:实现数据缓存的功能,有文件缓存(flieCache)内存缓存(MemoryCache),内存缓存和文件缓存按照接口约束实现

    • 定义一个泛型接口,约束实现它的子类必须有getByKey(key)setByKey(key,value)

    • 要求setByKey的时候的value的类型和实例化子类的时候的指定的类型一致

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      abstract class Cache<T>{                              //泛型接口,这个T表示类型校验
      void getByKey(String key);
      void setByKey(String key,T value); //泛型方法
      }
      class FlieCache<T> implements Cache<T>{ //想要实现泛型接口,实现它的类也必须是泛型类
      @override
      void getByKey(String key) {
      }
      @override
      void setByKey(String key, T value) {
      print('我是一个文件缓存,把$key$value 写入文件');
      }
      }
      class MemoryCache<T> implements Cache<T>{
      @override
      void getByKey(String key) {
      }
      @override
      void setByKey(String key, T value) {
      }
      }
      main(){
      FlieCache f=FlieCache<String>(); //实例化时填入指定类型,除了String,int,还能指定Map类型,List类型 如下:
      f.setByKey('index', '首页目录'); //调用时按照指定类型输入指定类型的数据,如果指定String类型却输入int类型数据的话就会报错
      } //输出: 我是一个文件缓存,把index 和首页目录 写入文件
      // FlieCache f=FlieCache<List>();
      // f.setByKey('index', ['首页目录',20]); //输出: 我是一个文件缓存,把index 和[首页目录 20] 写入文件
-------------本文有底学海无涯-------------