Dart學習總結(jié)

很詳細的Dart講解

Dart 數(shù)據(jù)類型

數(shù)據(jù)的操作 跟Java差不多

變量與常量

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

數(shù)值型

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

字符串

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

布爾型

var ,bool 定義
bool a = true

列表List(數(shù)組)

三種方法定義
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 動態(tài)變量類型,類似var

運算符

算數(shù)運算符,關系運算符,邏輯運算符,賦值運算符,條件表達式

  • , - ,*, / , ~/ , %
    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;

方法

返回值 方法名 (參數(shù)){
方法體
}

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

可選參數(shù)

//可變參數(shù)
printPersion(String name, {int age, String formal}) =>
    print("name = $name ,age = $age ,formal = $formal");

//位置固參數(shù)
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");

默認參數(shù)值

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

方法對象

Dart 中任何方法都是對象,可以賦值給變量 運行,也可以作為另一個方法的參數(shù)。。。
printHello() => print("hello shadow");
//方法作為對象賦值給變量aa,然后由aa執(zhí)行
var aa = printHello();
aa(); ==》hello shadow

匿名方法

(可選參數(shù)){方法體}
var name = (str) {
print("hello ---- $str");
};
name("shadow");

閉包

閉包函數(shù) 就是在一個函數(shù)內(nèi)部聲明的函數(shù),這樣就可以調(diào)用該函數(shù)的內(nèi)部變量
閉包內(nèi)的函數(shù)可以是正常函數(shù)也可以是匿名函數(shù)

void main() {
  var func = aaa();
  func(); -->0
  func(); -->1
  func(); -->2
  func(); -->3
  func(); -->4
}
//閉包函數(shù) 就是在一個函數(shù)內(nèi)部聲明的函數(shù)
aaa() {
  int count = 0;

  /*printCount() {
    print(count++);
  }
  return printCount;*/

  return (){
    print(count++); 
  };
}

Dart面向?qū)ο缶幊?/h3>

類和對象

Dart的類和對象跟Java差不多,結(jié)合kotlin

  • 使用關鍵字class聲明一個lei
  • 使用關鍵字new 創(chuàng)建一個對象,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 工作。。。。");
}

計算屬性

計算屬性的值是通過計算而來,本身不存儲值,計算屬性賦值,其實是通過極端轉(zhuǎn)換到其他實例變量

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;
}

構(gòu)造函數(shù)

  • 如果沒有自定義構(gòu)造方法,則會有個默認的構(gòu)造方法
  • 如果存在自定義構(gòu)造方法,則默認構(gòu)造方法無效
    因為Dart方法不允許重載,所以Dart想要有多個構(gòu)造函數(shù),只能用命名構(gòu)造函數(shù)
    使用類名.方法的形式實現(xiàn)
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; //傳統(tǒng)方式 不能對final屬性賦值
  }*/

//Dart蜜糖寫法,可以允許對final的屬性賦值,在構(gòu)造方法體執(zhí)行之前賦值
  People(this.age, this.name, this.address, this.weight) {}

//命名構(gòu)造方法,用以創(chuàng)建多個構(gòu)造方法
  People.withAge(this.age, this.weight) {}

//普通方法
  work() => print("name = $name , age = $age 在 $address 工作。。。。");
}

常量構(gòu)造方法

如果一個類中的變量值只需要賦值一次,則可以把這個類設置為常量構(gòu)造
常量構(gòu)造,需要此類中所以的變量都是final,并且構(gòu)造方法以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);
}

工廠構(gòu)造方法

  • 工廠構(gòu)造方法類似于設計模式中的工廠模式
  • 在構(gòu)造方法前添加關鍵字factory實現(xiàn)一個工廠構(gòu)造方法
  • 在工廠構(gòu)造方法中可返回對象
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); //私有構(gòu)造方法
}

初始化列表

  • 初始化列表會在構(gòu)造方法體執(zhí)行之前執(zhí)行
  • 使用分號分隔初始化表達式
  • 初始化列表常用于設置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"];
  }
}

靜態(tài)成員

  • 使用static關鍵字來實現(xiàn)類級別的變量和函數(shù)
  • 靜態(tài)成員不能訪問非靜態(tài)成員 非靜態(tài)成員可以訪問靜態(tài)成員
  • 類中的常量需要使用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);
  }
}

對象操作符

  • 條件成員訪問:?. -->判斷對象是否為空,不為空才去執(zhí)行后面的內(nèi)容
  • 類型轉(zhuǎn)換:as
  • 是否指定類型 is,is! --->判斷對象是否是指定的類型,返回true,false
  • 級聯(lián)操作:.. --->類似build模式,聯(lián)級調(diào)用
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中對象可作為方法使用,方法可作為對象使用
想要對象作為方法使用,需要在類中創(chuàng)建call(方法名)方法,參數(shù)值,方法體都沒有要求。。

void main() {
  CallClass callClass = CallClass();
  callClass("shadow", 18); //對象當做方法使用
}

class CallClass {
  String name;
  int age;

  call(name, age) => "name = $name ,age = $age";
}

面向?qū)ο髷U展 :封裝 繼承 多態(tài)

繼承,抽象,接口,mixins,操作符復寫

繼承

  • 使用extend 繼承類
  • 子類會繼承父類的可見屬性和方法,不會繼承構(gòu)造方法
  • 子類能夠復寫父類的方法、get 和set方法
  • 單繼承、 多態(tài)性
  • 子類的構(gòu)造方法會默認調(diào)用父類的無參構(gòu)造方法
  • 如果父類沒有無名無參構(gòu)造方法,則需要顯示調(diào)用父類的構(gòu)造方法
  • 在構(gòu)造方法參數(shù)后使用 :顯示調(diào)用父類的構(gòu)造方法
    構(gòu)造方法的執(zhí)行順序
  • 父類的構(gòu)造方法在子類構(gòu)造方法體開始執(zhí)行的位置調(diào)用
  • 如果有初始化列表,初始化列表必須放在父類構(gòu)造方法前面調(diào)用執(zhí)行
void main() {
  //多態(tài)
  Person p1 = Student("shadow", 18);
  print(p1.name);
  print((p1 as Student).age);
  print(p1);
}

class Person {
  String name;

  //構(gòu)造1
  Person(this.name);

  //構(gòu)造2
  Person.withName(this.name);
}

class Student extends Person {
  int age;
  //復寫構(gòu)造
  Student(String name, int age): this.age = age, super.withName(name);
//Student(String name) : super(name);
}

抽象類

  • 抽象類使用**abstract **表示 ,不能直接被實例化
  • 抽象方法不用**abstract **修飾,無實現(xiàn)即可,所以有時候 抽象類可作為接口使用
  • 抽象類可以沒有抽象方法
  • 有抽象方法的類一定得聲明為抽象類
void main() {
  var aaa = A();
  aaa.run();
}

abstract class AbstractClass {
  void run(); //抽象方法
}

class A extends AbstractClass {
  //實現(xiàn)抽象方法
  @override
  void run() {
    print("hello shadow");
  }
}

接口

  • 類和接口是統(tǒng)一的,類就是接口
  • 每個類都隱式的定義了一個包含所有實例成員的接口
  • 如果是服用已有類的實現(xiàn),使用繼承(extends)
  • 如果只是使用已有類的外在行為,使用接口(implements)
  • Dart中抽象類更像接口,所以根據(jù)情況使用
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 實現(xiàn)多繼承

  • Mixins 類似于多繼承,是在多類繼承中重用的一個類代碼的方式
  • 作為Mixin的類不能有顯示聲明構(gòu)造方法
  • 作為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...  與多繼承的順序有關,如果繼承的多個類中有相同的方法,調(diào)用最后一個類的方法
}

另外一種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;
  //構(gòu)造函數(shù)
  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、系統(tǒng)內(nèi)置庫
import 'dart:math';

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

網(wǎng)絡請求庫
import 'dart:io';
import 'dart:convert';
async和await
這兩個關鍵字的使用只需要記住兩點:
只有async方法 才能使用 await關鍵字 調(diào)用方法
如果調(diào)用別的async方法 必須使用 await關鍵字
async是讓方法變成異步。
await是等待異步方法執(zhí)行完成。

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、創(chuàng)建HttpClient對象
  var httpClient = new HttpClient();  
  //2、創(chuàng)建Uri對象
  var uri = new Uri.http('news-at.zhihu.com','/api/3/stories/latest');
  //3、發(fā)起請求,等待請求
  var request = await httpClient.getUrl(uri);
  //4、關閉請求,等待響應
  var response = await request.close();
  //5、解碼響應的內(nèi)容
  return await response.transform(utf8.decoder).join();
}

3、Pub包管理系統(tǒng)中的庫
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; 只能調(diào)用foo方法
模式二:隱藏不需要的部分,使用hide關鍵字,如下例子所示:
import 'package:lib2/lib2.dart' hide foo; 只有foo方法不能調(diào)用
延遲加載
也稱為懶加載,可以在需要的時候再進行加載。
懶加載的最大好處是可以減少APP的啟動時間。
懶加載使用deferred as關鍵字來指定,如下例子所示:
import 'package:deferred/hello.dart' deferred as hello;
當需要使用的時候,需要使用loadLibrary()方法來加載:
greet() async {
await hello.loadLibrary();
hello.printGreeting();
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容