Dart学习总结

很详细的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 _map = {}; //私有属性
  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();
  list.add("hello");
  var util = Utils();
  util.put(10);
}

class Utils {
  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 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学习总结)