Dart学习笔记-基础篇

作者: 蜗牛学开车 | 来源:发表于2020-09-08 19:09 被阅读0次

    声明

    本笔记是我自己在学习Dart语言基础的时候做的笔记。有些代码只是为了演示用法,不要纠结逻辑。

    本笔记是站在一个Android开发者的角度上记录的,Dart中与Java相同的地方没有做记录,请谅解。阅读本笔记将默认你是一个Android或Java开发者。

    一、声明变量与常量

    Dart中声明变量有以下几种方式:

    //第一种方式
    var str = '这是字符串';
    var str2 = "这是字符串2";
    var str3 = '''
        这是字符串3
        这是字符串3的第二行
        ''';
    var str4 = """
        这是字符串4
        这是字符串4的第二行
        """;
    var age = 24;
    
    //第二种方式
    String str = '这是字符串';
    int age = 25;
    

    Dart中的常量使用finalconst关键字修饰,const定义时就要赋值,final可以使用时在赋值,final也是运行时常量,在运行时也不能被修改。

    //使用final定义。
    final String name = '李四';
    final int age = 24;
    //使用const定义。
    const String gender = '男';
    const int height = 165;
    

    二、自定义函数

    1. 可选参数

    可选参数的作用就类似Java语言中的方法重载。

    /**
     * 定义可选参数的自定义函数。
     * @userName 为必传参数。
     * @age 可选参数
     */
    String printUserInfo(String userName, [int age]){
      return "姓名:$userName-年龄:${age==null??"未知"}";
    }
    
    //调用演示
    print(printUserInfo("张三"));
    
    print(printUserInfo("李四", 24));
    
    //输出结果
    姓名:张三-年龄:未知
    姓名:李四-年龄:24
    

    2. 可选参数-带默认值

    可选参数也支持赋值默认值,也就是说,如果调用方法的时候没有传该参数,那么就就会使用默认值赋值。

    /**
     * 定义可选参数的自定义函数。
     * @userName 为必传参数。
     * @gander 可选参数
     * @age 可选参数
     */
    String printUserInfo(String userName, [String gender='男', int age]){
      return "姓名:$userName-性别:$gender-年龄:${age==null??"未知"}";
    }
    
    //调用演示
    print(printUserInfo("张三"));
    
    print(printUserInfo("小微", '女'));
    
    //输出结果
    姓名:张三-性别:男-年龄:未知
    姓名:小微-性别:女-年龄:未知
    

    3. 命名参数

    命名参数几乎和可选参数一样,只是有以下两点不同:

    1).写法不同,要将[]中括号换成{}花括号。

    2).用法不同,可选参数在调用时必须按照方法中声明的顺序传参,而命名参数则不需要按照顺序。这是因为命名参数在传参时必须制定参数名。

    /**
     * 定义命名参数的自定义函数。
     * @userName 为必传参数。
     * @gander 可选参数
     * @age 可选参数
     */
    String printUserInfo(String userName, {String gender='男', int age=23}){
      return "姓名:$userName-性别:$gender-年龄:$age";
    }
    
    //调用演示
    print(printUserInfo("张三", age:20));
    
    print(printUserInfo("小微", age:18, gender:'女'));
    
    //输出结果
    姓名:张三-性别:男-年龄:20
    姓名:小微-性别:女-年龄:18
    

    4. 把方法做为参数

    其实就是参数类型为一个Function。

    //第一种方式
    void fn1(fn){
      fn();
    }
    
    void fn2(){
      print('这里是方法2');
    }
    
    //调用演示
    fn1(fn2);
    
    
    //第二种方式
    var fn3 = (){
        print('这里是方法3');
    };
    
    //调用演示
    fn1(fn3);
    
    //输出结果
    这里是方法2
    这里是方法3
    

    5. 匿名函数

    //无参匿名方法
    var fun1 = (){
      print('无参匿名方法');
    };
    //有参匿名方法
    var fun2 = (String arg){
        print(arg);
    };
    

    三、类

    1. 权限修饰符

    Dart语言中并没有像Java一样有publicprivateprotected这些权限修饰符。Dart中只有一个权限修饰符_(下划线)。下划线修饰符类似于Java中的默认修饰符,在同一个.dart文件中是公开的,不同的.dart文件中是私有的。

    class Persion{
      //私有成员变量姓名。
      String _name;
      //私有成员变量年龄
      int _age;
    
      //构造方法
      Persion(String name, int age){
        _init(name, age);
      }
    
      //私有init方法。
      void _init(String name, int age){
        this._name = name;
        this._age = age;
      }
    
      //公共方法获取姓名。
      String getName(){
        return this._name;
      }
    
      //公共方法获取年龄。
      int getAge(){
        return this._age;
      }
    }
    

    2. 构造方法

    ​ 1). 默认的构造方法与Java一样,但Dart支持可选参数

    ​ 2).命名构造

    ​ 命名构造顾名思义就是给构造方法定义一个名字,在使用的时候直接使用这个名字即可,其实在使用时的代码看起来更像是Java中的静态方法,只是在静态方法中返回了这个对象而已。

    class Persion{
    
      String name;
      int age;
    
      /**
       * 定义命名构造
       */
      Persion.create(String name, int age){
        this.name = name;
        this.age = age;
      }
    }
    
    //使用
    var persion = Persion.create("张三", 23);
    
    print("${persion.name}-${persion.age}")
    
    //输出
    张三-23
    

    3. getter 和 setter 方法

    Dart中的方法与Java中的方法一样,在调用时后面必须要跟上(),比如persion.getName(),但是使用get或set定义方法后就可以像成员变量一样使用。

    class Persion{
    
      String _name;
      int _age;
    
      /**
       * 定义命名构造
       */
      Persion(String name, int age){
        this._name = name;
        this._age = age;
      }
    
      get isBaby{
        return this._age <= 2;
      }
    
      set age(int age){
        this._age = age;
      }
    }
    
    //使用
    var persion = new Persion('张三', 23);
    persion.age = 1;
    
    print(persion.isBaby);
    
    //输出
    true
    

    4. 初始化列表

    在Dart中我们可以在构造方法执行之前初始化对象的变量。

    class Persion{
    
      String name;
      int age;
    
      /**
       * 定义命名构造
       */
      Persion(): this.name = '李四', this.age = 24{
      }
    }
    
    //使用
    var persion = new Persion();
    print("${persion.name}-${persion.age}");
    
    //输出
    李四-24
    

    5. 静态属性和静态方法

    Dart中的静态属性和静态方法与Java中一致,静态方法中不能访问非静态成员,非静态方法中可以访问静态成员。

    class Persion{
      static String name = '王五';
      static int age = 25;
    
      static isBaby(){
        return age <= 2;
      }
    }
    
    //使用
    print("${Persion.name}-${Persion.age}-${Persion.isBaby()}");
    
    //输出
    王五-25-false
    

    6. 对象操作符

    1. ? 条件运算符

      var persion
      persion?.getName() //加上 ? 表示如果persion为null则不会getName方法,相当于非null判断。
      
    2. as 类型转换符(强转)

    3. is 类型判断(相当于Java中的instanceOf)

    4. .. 级联操作(连缀)

      class Persion{
        String name;
        int age;
      
        void printInfo(){
          print("$name-$age");
        }
      }
      
      //使用
      Persion persion = new Persion();
      
      persion..name = '赵六'
             ..age = 36
             ..printInfo();
      
      //输出
      赵六-26
      

    7. 继承

    Dart中关于继承的规则基本和Java一致。

    class Persion{
      String name;
      int age;
    
      Persion(String name, int age){
          this.name = name;
          this.age = age;
      }
    
      void printInfo(){
        print("$name-$age");
      }
    }
    
    class Man extends Persion{
      Man(String name, int age) : super(name, age);//如果父类没有空参构造子类就必须要调用父类的构造。
    }
    
    //使用
    var man = new Man('如花', 28)
    man.printInfo()
      
    //输出
    如花-28
    

    上面的代码是正常的继承关系,下面是被继承的类有命名构造。

    class Persion{
      String name;
      int age;
    
      Persion.create(String name, int age){
          this.name = name;
          this.age = age;
      }
    
      void printInfo(){
        print("$name-$age");
      }
    }
    
    class Man extends Persion{
      Man(String name, int age) : super.create(name, age);//调用super的命名构造。
    }
    

    复写父类方法。

    class Man extends Persion{
      Man(String name, int age) : super.create(name, age);
    
      //覆盖父类的方法
      @override
      void printInfo() {
        print('我是一个男人');
      }
    }
    

    其他的基本与Java一致,这里就不再详细记录了。

    四、抽象类&接口

    Dart中的抽象类充当了Java中的接口和抽象类,Dart中可以子类可以继承抽象类也可以实现抽象类接口。由于Dart中没有interface关键字所以定义接口时推荐使用抽象类,只是子类实现时不是使用extends而是使用implements

    1. 抽象类

    abstract class Fruits{
      String taste();
    }
    
    class Apple extends Fruits{
      
      String name;
    
      Apple(String this.name);
    
      @override
      String taste() {
        return "${name}苹果又甜又脆";
      }
    }
    
    //使用
    Fruits fruits = new Apple("红富士");
    
    print(fruits.taste());
    
    //输出
    红富士苹果又甜又脆
    

    2. 接口

    接口使用implements关键字而不是extends

    abstract class Fruits{
      String taste();
    }
    
    class Apple implements Fruits{
      
      String name;
    
      Apple(String this.name);
    
      @override
      String taste() {
        return "${name}苹果又甜又脆";
      }
    }
    
    class Durian implements Fruits{
      @override
      String taste() {
        return '榴莲味道臭臭的但吃起来香';
      }
    }
    
    //使用
    Fruits fruits = new Apple("烟台");
    print(fruits.taste());
    
    fruits = new Durian();
    print(fruits.taste());
    
    //输出
    烟台苹果又甜又脆
    榴莲味道臭臭的但吃起来香
    

    使用implements关键字实现和extends继承,有什么区别?答案是,如果是用implements的话,那么接口中的所有方法子类都必须要复写。如果使用extends则只需要复写抽象方法即可。由此可以说明以下两点:

    1. 一个类到底是接口还是抽象类还是普通类,得看子类使用的是extends继承还是implements实现。
    2. 抽象类中可以有抽象方法,也可以有非抽象方法,什么样的方法是抽象方法?没有方法体的方法就是抽象方法。

    注意,Dart与Java一样,只可以多实现不可以多继承。

    3. mixins混合类

    混合类其实是一个类似多继承的这么一个功能。为什么说类似多继承?因为从代码上看,它确实很像多继承。但使用mixins还有以下几个条件:

    1. 做为mixins的类只能继承自Object,不能继承其他类。
    2. 做为mixins的类不能有构造函数。
    3. 一个类可以mixins多个mixins类。
    4. mixins绝不是继承,也不是接口,而是Dart语言的一种全新的特性。
    class Persion{
        void work(){
          print('人类都需要工作');
        }
    }
    
    
    class ET{
      void address(){
        print('外星人生活在其他星球');
      }
    }
    
    //mixins混合类。
    class A with Persion, ET {}
    
    //使用
    var a = new A();
    //混合类a即有Persion的方法又有ET的方法。其实就是class A,把这两个类给混合在了一起。
    a.work();  
    a.address();
    
    //输出
    人类都需要工作
    外星人生活在其他星球
    

    对混合类使用is进行类型判断的时候,会满足它所混合的所有类。

    var a = new A();
    
    print(a is Persion);
    print(a is ET);
    
    //输出
    true
    true
    

    五、泛型

    Dart中的泛型与Java中的泛型在使用上基本没有什么区别。只是有一点暂时不是很清楚,那就是不知道Dart中有没有类型擦除的概念。写demo是发现使用泛型后传入不同类型的数据在运行时会报错,不知道这是不是意味着Dart语言没有类型擦除。关于类型擦除以后再来研究,以后再来补齐这里的资料。

    六、库

    每一个.dart文件就是一个库。

    1. 系统库

    import 'dart:convert';
    import 'dart:io';
    

    2. 自定义库

    impot 'lib/Persion.dart';
    

    3. 三方库

    Pub包管理系统中的库。

    三方库的使用方法有以下几步:

    1. 需要在自己的项目的根目录中创建一个pubspec.yaml文件。

    2. 在pubspec.yaml文件中配置三方库的名称、描述、依赖等信息。

    3. 运行 pub get 命令将三方库下载到本地。

    4. 在项目中要使用的.dart文件中引入三方库,例如:

      import 'package:http/http.dart' as http;
      

    4. 库的重命名

    在导入的不同的库中存在相同名称的类时,直接使用类将会报错,因为编译器不知道你要使用的是哪个类,这时就需要用到库的重命名功能(导包时使用as为库重命名)。

    import 'persion1.dart';
    import 'persion1.dart' as p2;
    
    main(){
        //构建persion1库中的Persion对象。
        Persion persion = new Persion();
        
        //构建persion2库中的Persion对象。
        p2.Persion persion2 = p2.Persion();
    }
    

    七、同步异步

    调用异步方法要使用await关键字,而await关键字必须在async的方法中使用。async就是把方法变成异步方法,await就是等待异步方法执行完成。

    main(List<String> args) async {
      var reqServer = await HttpServer.bind('192.168.0.100', 8080);
      print('服务已启动');
      await for (HttpRequest req in reqServer) {
        handleMessage(req);
      }
    }
    

    相关文章

      网友评论

        本文标题:Dart学习笔记-基础篇

        本文链接:https://www.haomeiwen.com/subject/prujektx.html