美文网首页
Dart学习总结

Dart学习总结

作者: 付小影子 | 来源:发表于2019-05-09 14:15 被阅读0次

    很详细的Dart讲解

    Dart 数据类型

    数据的操作 跟Java差不多

    变量与常量

    var ,const,final
    var a= 10;
    a = “10”
    a = true

    数值型

    var ,num (基类) int,double 子类

    字符串

    var ,String
    String a = "h";
    print(a*3) --->hhh

    布尔型

    var ,bool 定义
    bool a = true

    列表List(数组)

    三种方法定义
    var a = ["a",1,true,12.5]; 可以是任意类型
    var b = const[1,2,3,4,5];不可变 list
    List list = new List();
    print(a[1]) == >1

    Map

    var map = {"first":"hello","1":1,2:"shadow","3":true,true:23}
    map.constKey(2) ==>true

    dynamic 动态变量类型,类似var

    运算符

    算数运算符,关系运算符,逻辑运算符,赋值运算符,条件表达式

    • , - ,*, / , ~/ , %
      3/2 == > 1.5
      3 ~/ 2 ===>1
      && , ||

    赋值运算符 =,??

    var a;
    var k = "dart";
    var c = "java";
    var d = a ?? c;
    print(d); ==》java
    var g = k ?? c;
    print(g); ==>dart

    控制语句

    if,for,while,break,continue,switch...case;

    方法

    返回值 方法名 (参数){
    方法体
    }

    String test(var a){
    return a;
    }
    等价
    test(var a) =>a 
    

    可选参数

    //可变参数
    printPersion(String name, {int age, String formal}) =>
        print("name = $name ,age = $age ,formal = $formal");
    
    //位置固参数
    printPersion2(String name, [int age, String formal]) =>
        print("name = $name ,age = $age ,formal = $formal");
    
    printPersion("shadow");
      printPersion("shadow", age: 18);
      printPersion("shadow", formal: "meal");
      printPersion("shadow", age: 18, formal: "meal");
    
      printPersion2("ying");
      printPersion2("ying", 12);
      printPersion2("ying", 12, "male");
    

    默认参数值

    printPersion(String name, {int age = 15, String formal}) =>
        print("name = $name ,age = $age ,formal = $formal");
    

    方法对象

    Dart 中任何方法都是对象,可以赋值给变量 运行,也可以作为另一个方法的参数。。。
    printHello() => print("hello shadow");
    //方法作为对象赋值给变量aa,然后由aa执行
    var aa = printHello();
    aa(); ==》hello shadow

    匿名方法

    (可选参数){方法体}
    var name = (str) {
    print("hello ---- $str");
    };
    name("shadow");

    闭包

    闭包函数 就是在一个函数内部声明的函数,这样就可以调用该函数的内部变量
    闭包内的函数可以是正常函数也可以是匿名函数

    void main() {
      var func = aaa();
      func(); -->0
      func(); -->1
      func(); -->2
      func(); -->3
      func(); -->4
    }
    //闭包函数 就是在一个函数内部声明的函数
    aaa() {
      int count = 0;
    
      /*printCount() {
        print(count++);
      }
      return printCount;*/
    
      return (){
        print(count++); 
      };
    }
    

    Dart面向对象编程

    类和对象

    Dart的类和对象跟Java差不多,结合kotlin

    • 使用关键字class声明一个lei
    • 使用关键字new 创建一个对象,new可以省略
    • 所有对象都继承Object类
    • 属性默认会生成getter&setter方法
    • 使用final声明的属性只有getter方法
    • 属性和方法可以可以 . 访问
    • 方法不能被重载
    • Dart中可见性以library(库)为单位
    • 默认情况下 每一个Dart文件就是一个库
    • 使用 _ 表示库的私有性:int _name ;私有属性 class _persion{} 私有类
    • 使用import导入库
    void main() {
      var people = People();
      people.name = "shadow";
      people.age = 18;
      print( people.name);
      people.work();
    }
    
    class People {
      int age;
      String name;
      String address;
    
      work() => print("name = $name , age = $age 在 $address 工作。。。。");
    }
    

    计算属性

    计算属性的值是通过计算而来,本身不存储值,计算属性赋值,其实是通过极端转换到其他实例变量

    void main() {
      var ma = aaa();
      print(ma.area);
      print(ma.computeArea());
    }
    
    class aaa {
      num width, height;
      num get area => width * height; //计算属性 get方法
      set area(value) { //计算属性 set方法
        width = value / 10;
        return width * height
      }
    //方法计算 面积
      computeArea() => width * height;
    }
    

    构造函数

    • 如果没有自定义构造方法,则会有个默认的构造方法
    • 如果存在自定义构造方法,则默认构造方法无效
      因为Dart方法不允许重载,所以Dart想要有多个构造函数,只能用命名构造函数
      使用类名.方法的形式实现
    class People {
      int age;
      String name;
      String address;
      final String weight;
    
    /*  People (int age,String name,String address,String weight){
        this.age = age;
        this.name = name;
        this.address = address;
        this.weight = weight; //传统方式 不能对final属性赋值
      }*/
    
    //Dart蜜糖写法,可以允许对final的属性赋值,在构造方法体执行之前赋值
      People(this.age, this.name, this.address, this.weight) {}
    
    //命名构造方法,用以创建多个构造方法
      People.withAge(this.age, this.weight) {}
    
    //普通方法
      work() => print("name = $name , age = $age 在 $address 工作。。。。");
    }
    

    常量构造方法

    如果一个类中的变量值只需要赋值一次,则可以把这个类设置为常量构造
    常量构造,需要此类中所以的变量都是final,并且构造方法以const修饰

    void main() {
      const people = const People(18, "shadow", "上海", "50");
      print(people.age);
      print(people.name);
    }
    
    class People {
      final int age;
      final String name;
      final String address;
      final String weight;
    
      const People(this.age, this.name, this.address, this.weight);
    }
    

    工厂构造方法

    • 工厂构造方法类似于设计模式中的工厂模式
    • 在构造方法前添加关键字factory实现一个工厂构造方法
    • 在工厂构造方法中可返回对象
    class Logger {
      final String name;
      static final Map<String, Logger> _map = <String, Logger>{}; //私有属性
      factory Logger(String name) {
        if (_map.containsKey(name)) {
          return _map[name];
        } else {
          final logger = Logger._withName(name);
          _map[name] = logger;
          return logger;
        }
      }
    
      Logger._withName(this.name); //私有构造方法
    }
    

    初始化列表

    • 初始化列表会在构造方法体执行之前执行
    • 使用分号分隔初始化表达式
    • 初始化列表常用于设置final变量的值
    class ListStru {
      String name;
      int age;
      final int weight;
    
      ListStru(Map map): this.name = map["name"], this.weight = map["weight"] {
        this.age = map["age"];
      }
    }
    

    静态成员

    • 使用static关键字来实现类级别的变量和函数
    • 静态成员不能访问非静态成员 非静态成员可以访问静态成员
    • 类中的常量需要使用static const声明
    void main() {
      StaticNum.currentPage = 10;
      StaticNum.aaa();
    
      var num = StaticNum();
      num.bbb();
    }
    
    class StaticNum {
      static int currentPage;
      static const int weight = 100;
    
      static aaa() {
        currentPage++;
        print(currentPage);
      }
    
      bbb() {
        currentPage--;
        print(currentPage);
      }
    }
    

    对象操作符

    • 条件成员访问:?. -->判断对象是否为空,不为空才去执行后面的内容
    • 类型转换:as
    • 是否指定类型 is,is! --->判断对象是否是指定的类型,返回true,false
    • 级联操作:.. --->类似build模式,联级调用
    void main() {
      var num2;
      if (num2 is StaticNum) {
        num2?.bbb();
      }
      num2 = StaticNum();
      (num2 as StaticNum)?.bbb();
      
      (num2 as StaticNum)
        ..age = 10
        ..name = "shadow"
        ..bbb();
    }
    
    class StaticNum {
      int age;
      String name;
    
      bbb() {
        print("name = $name ,age = $age");
      }
    }
    

    对象call方法(不建议使用,会让代码复杂化)

    在Dart中对象可作为方法使用,方法可作为对象使用
    想要对象作为方法使用,需要在类中创建call(方法名)方法,参数值,方法体都没有要求。。

    void main() {
      CallClass callClass = CallClass();
      callClass("shadow", 18); //对象当做方法使用
    }
    
    class CallClass {
      String name;
      int age;
    
      call(name, age) => "name = $name ,age = $age";
    }
    
    

    面向对象扩展 :封装 继承 多态

    继承,抽象,接口,mixins,操作符复写

    继承

    • 使用extend 继承类
    • 子类会继承父类的可见属性和方法,不会继承构造方法
    • 子类能够复写父类的方法、get 和set方法
    • 单继承、 多态性
    • 子类的构造方法会默认调用父类的无参构造方法
    • 如果父类没有无名无参构造方法,则需要显示调用父类的构造方法
    • 在构造方法参数后使用 :显示调用父类的构造方法
      构造方法的执行顺序
    • 父类的构造方法在子类构造方法体开始执行的位置调用
    • 如果有初始化列表,初始化列表必须放在父类构造方法前面调用执行
    void main() {
      //多态
      Person p1 = Student("shadow", 18);
      print(p1.name);
      print((p1 as Student).age);
      print(p1);
    }
    
    class Person {
      String name;
    
      //构造1
      Person(this.name);
    
      //构造2
      Person.withName(this.name);
    }
    
    class Student extends Person {
      int age;
      //复写构造
      Student(String name, int age): this.age = age, super.withName(name);
    //Student(String name) : super(name);
    }
    

    抽象类

    • 抽象类使用**abstract **表示 ,不能直接被实例化
    • 抽象方法不用**abstract **修饰,无实现即可,所以有时候 抽象类可作为接口使用
    • 抽象类可以没有抽象方法
    • 有抽象方法的类一定得声明为抽象类
    void main() {
      var aaa = A();
      aaa.run();
    }
    
    abstract class AbstractClass {
      void run(); //抽象方法
    }
    
    class A extends AbstractClass {
      //实现抽象方法
      @override
      void run() {
        print("hello shadow");
      }
    }
    

    接口

    • 类和接口是统一的,类就是接口
    • 每个类都隐式的定义了一个包含所有实例成员的接口
    • 如果是服用已有类的实现,使用继承(extends)
    • 如果只是使用已有类的外在行为,使用接口(implements)
    • Dart中抽象类更像接口,所以根据情况使用
    class Person{
      String Name;
      int age;
      
      run() => print("hello shadow");
    }
    class InterfaceClass implements Person{
      @override
      String Name;
    
      @override
      int age;
    
      @override
      run() {
        return "hello world";
      }
    }
    

    mixins 实现多继承

    • Mixins 类似于多继承,是在多类继承中重用的一个类代码的方式
    • 作为Mixin的类不能有显示声明构造方法
    • 作为Mixin的类只能继承自Object
    • 使用关键字with连接一个或者多个mixin
    //不能有显示声明,不能继承别的类
    class A {
      a() => print("A.a...");
    }
    
    class B {
      a() => print("B.a...");
    
      b() => print("B.b...");
    }
    
    class C {
      a() => print("C.a...");
    
      b() => print("C.b...");
    
      c() => print("C.c...");
    }
    
    class D extends A with B, C {}
    
    void main() {
      var d = D();
      d.a(); //C.a...  与多继承的顺序有关,如果继承的多个类中有相同的方法,调用最后一个类的方法
    }
    

    另外一种mixins的使用方式

    abstract class Engine {
      void work();
    }
    
    class OilEngine implements Engine {
      @override
      void work() {
        print("Work with oil....");
      }
    }
    class ElectricEngine implements Engine {
      @override
      void work() {
        print("Work with Electric....");
      }
    }
    
    class Tyre {
      String name;
      void run() {}
    }
    
    class Bus = Tyre with OilEngine;
    class Car = Tyre with ElectricEngine;
    
    /*
    class Car extends Tyre with ElectricEngine{
      
    }*/
    abstract class Engine {
      void work();
    }
    
    class OilEngine implements Engine {
      @override
      void work() {
        print("Work with oil....");
      }
    }
    class ElectricEngine implements Engine {
      @override
      void work() {
        print("Work with Electric....");
      }
    }
    
    class Tyre {
      String name;
      void run() {}
    }
    
    class Bus = Tyre with OilEngine;
    class Car = Tyre with ElectricEngine;
    
    /*
    class Car extends Tyre with ElectricEngine{
      
    }*/
    

    操作符 复写

    111.png 222.png
    void main() {
      var p1 = PersonA(18);
      var p2 = PersonA(20);
    
      print(p1 > p2); //---》 false
    
      print(p1["age"]);
    
      print(p1 == p2);
    }
    
    class PersonA {
      int age;
      //构造函数
      PersonA(this.age);
      //重写操作符
      bool operator >(PersonA p) {
        return this.age > p.age;
      }
      int operator [](str) {
        if ("age" == str) {
          return age;
        }
        return 0;
      }
    
      @override
      bool operator ==(Object other) =>
          identical(this, other) ||
          other is PersonA && runtimeType == other.runtimeType && age == other.age;
    
      @override
      int get hashCode => age.hashCode;
    }
    
    

    Dart 枚举

    333.png 444.png
    void main() {
      var currentSeason = Season.spring;
      print(currentSeason.index); // == > 0
      switch (currentSeason) {
        case Season.spring:
          print("1 - 3月");
          break;
        case Season.summer:
          print("1 - 3月");
          break;
        case Season.autumn:
          print("1 - 3月");
          break;
        case Season.winter:
          print("1 - 3月");
          break;
      }
    }
    
    //定义枚举
    enum Season { spring, summer, autumn, winter }
    

    泛型

    555.png 666.png
    void main() {
      var list = List<String>();
      list.add("hello");
      var util = Utils<int>();
      util.put(10);
    }
    
    class Utils<T> {
      T element;
    
      void put(T element) {
        this.element = element;
      }
    }
    

    dart导入库

    在Dart中,库的使用时通过import关键字引入的。
    Dart中的库主要有三种:
    1、我们自定义的库,就是引用别的类(工具类 实体类等)
    import 'lib/xxx.dart';
    2、系统内置库
    import 'dart:math';

    import "dart:math";
    main(){
        print(min(12,23));
        print(max(12,25));    
    }
    

    网络请求库
    import 'dart:io';
    import 'dart:convert';
    async和await
    这两个关键字的使用只需要记住两点:
    只有async方法 才能使用 await关键字 调用方法
    如果调用别的async方法 必须使用 await关键字
    async是让方法变成异步。
    await是等待异步方法执行完成。

    import 'dart:io';
    import 'dart:convert';
    
    void main() async{
      var result = await getDataFromZhihuAPI();
      print(result);
    }
    //api接口: http://news-at.zhihu.com/api/3/stories/latest
    getDataFromZhihuAPI() async{
      //1、创建HttpClient对象
      var httpClient = new HttpClient();  
      //2、创建Uri对象
      var uri = new Uri.http('news-at.zhihu.com','/api/3/stories/latest');
      //3、发起请求,等待请求
      var request = await httpClient.getUrl(uri);
      //4、关闭请求,等待响应
      var response = await request.close();
      //5、解码响应的内容
      return await response.transform(utf8.decoder).join();
    }
    

    3、Pub包管理系统中的库
    https://pub.dev/packages
    https://pub.flutter-io.cn/packages
    https://pub.dartlang.org/flutter/
    1、需要在自己想项目根目录新建一个pubspec.yaml
    2、在pubspec.yaml文件 然后配置名称 、描述、依赖等信息
    name: xxx
    description: A new flutter module project.
    dependencies:
    http: ^0.12.0+2
    date_format: ^1.0.6
    3、然后运行 pub get 获取包下载到本地 (termial或者cd 进入该项目目录,打开命令面板)
    4、项目中引入库 import 'package:http/http.dart' as http; 看文档使用

    import 'dart:convert' as convert;
    import 'package:http/http.dart' as http;
    
    main(List<String> arguments) async {
      // This example uses the Google Books API to search for books about http.
      // https://developers.google.com/books/docs/overview
      //var url = "https://www.googleapis.com/books/v1/volumes?q={http}";
      var url = "http://news-at.zhihu.com/api/3/stories/latest";
    
      // Await the http get response, then decode the json-formatted responce.
      var response = await http.get(url);
      if (response.statusCode == 200) {
        //返回的json字符串
        var jsonResponse = convert.jsonDecode(response.body);
        //读取json字符串中的字段
        var itemCount = jsonResponse['date'];
        print("Number of books about http: $itemCount.");
      } else {
        print("Request failed with status: ${response.statusCode}.");
      }
    }
    
    

    Dart库的重命名 Dart冲突解决 ---- as 关键词
    部分导入
    如果只需要导入库的一部分,有两种模式:
    模式一:只导入需要的部分,使用show关键字,如下例子所示:
    import 'package:lib1/lib1.dart' show foo; 只能调用foo方法
    模式二:隐藏不需要的部分,使用hide关键字,如下例子所示:
    import 'package:lib2/lib2.dart' hide foo; 只有foo方法不能调用
    延迟加载
    也称为懒加载,可以在需要的时候再进行加载。
    懒加载的最大好处是可以减少APP的启动时间。
    懒加载使用deferred as关键字来指定,如下例子所示:
    import 'package:deferred/hello.dart' deferred as hello;
    当需要使用的时候,需要使用loadLibrary()方法来加载:
    greet() async {
    await hello.loadLibrary();
    hello.printGreeting();
    }

    相关文章

      网友评论

          本文标题:Dart学习总结

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