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{
}*/
操作符 復寫


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 枚舉


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 }
泛型


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