Dart基礎(chǔ)知識(shí)匯總

1 介紹

Dart是由谷歌開(kāi)發(fā)的計(jì)算機(jī)編程語(yǔ)言,它可以被用于web纺腊、服務(wù)器畔师、移動(dòng)應(yīng)用 和物聯(lián)網(wǎng)等領(lǐng)域的開(kāi)發(fā)娶靡。

Dart誕生于2011年,號(hào)稱(chēng)要取代JavaScript看锉。但是過(guò)去的幾年中一直不溫不火姿锭。直到Flutter的出現(xiàn)現(xiàn)在被人們重新重視塔鳍。

要學(xué)Flutter的話(huà)我們必須首先得會(huì)Dart。

官網(wǎng):https://dart.dev/

2 環(huán)境搭建

要在我們本地開(kāi)發(fā)Dart程序的話(huà)首先需要安裝Dart SDK

官方文檔:https://dart.dev/get-dart呻此。

windows環(huán)境

http://www.gekorm.com/dart-windows/轮纫。

mac環(huán)境

參考上一篇文章, Mac搭建Flutter+Dart開(kāi)發(fā)環(huán)境

3 開(kāi)發(fā)工具

Dart的開(kāi)發(fā)工具有很多: IntelliJ IDEA 焚鲜、 WebStorm掌唾、 Atom、VS Code等

這里我們主要給大家講解的是如果在VS Code中配置Dart忿磅。

1 安裝VS Code https://code.visualstudio.com/郑兴。

2 找到VS Code插件安裝dart。

3 找到VS Code插件安裝code runner Code Runner 可以運(yùn)行我們的文件贝乎。

4 變量 常量 命名規(guī)則

變量

dart是一個(gè)強(qiáng)大的腳本類(lèi)語(yǔ)言情连,可以不預(yù)先定義變量類(lèi)型 ,自動(dòng)會(huì)類(lèi)型推倒览效。
dart中定義變量可以通過(guò)var關(guān)鍵字可以通過(guò)類(lèi)型來(lái)申明變量却舀。
注意:var 后就不要寫(xiě)類(lèi)型,寫(xiě)了類(lèi)型不要var 兩者都寫(xiě) var a int = 5; 報(bào)錯(cuò)锤灿。

var str = 'this is var';
String str = 'this is var';
int str = 123;
常量

final 和 const修飾符
const值不變 一開(kāi)始就得賦值挽拔。
final 可以開(kāi)始不賦值 只能賦一次 ; 而final不僅有const的編譯時(shí)常量的特性,最重要的它是運(yùn)行時(shí)常量但校,并且final是惰性初始化螃诅,即在運(yùn)行時(shí)第一次使用前才初始化。
永遠(yuǎn)不改量的量状囱,請(qǐng)使用final或const修飾它术裸,而不是使用var或其他變量類(lèi)型。

final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere
命名規(guī)則

1亭枷、變量名稱(chēng)必須由數(shù)字袭艺、字母、下劃線和美元符($)組成叨粘。
2猾编、注意:標(biāo)識(shí)符開(kāi)頭不能是數(shù)字。
3升敲、標(biāo)識(shí)符不能是保留字和關(guān)鍵字答倡。
4、變量的名字是區(qū)分大小寫(xiě)的如: age和Age是不同的變量。在實(shí)際的運(yùn)用中,也建議,不要用一個(gè)單詞大小寫(xiě)區(qū)分兩個(gè)變量。
5百匆、標(biāo)識(shí)符(變量名稱(chēng))一定要見(jiàn)名思意 :變量名稱(chēng)建議用名詞娩井,方法名稱(chēng)建議用動(dòng)詞设江。

5 數(shù)據(jù)類(lèi)型

常用數(shù)據(jù)類(lèi)型:

Numbers(數(shù)值)

int 必須是整型
double 既可以是整型 也可是浮點(diǎn)型

Strings(字符串)

String
字符串定義的幾種方式

var str1 = 'this is str1';

var str2 = "this is str2";

String str1 = 'this is str1';

String str2 = "this is str2";

/// 三個(gè)'''或者三個(gè)"""可以多行
String str1 = '''
this is str1
this is str1
this is str1
''';

String str = """
this is str1
this is str1
this is str1
""";

字符串的拼接

String str1 = '你好';

String str2 = 'Dart';

print("$str1 $str2");

print(str1 + str2);

print(str1 +" "+ str2);
Booleans(布爾)

bool

List(數(shù)組)

在Dart中锦茁,數(shù)組是列表對(duì)象,所以大多數(shù)人只是稱(chēng)它們?yōu)榱斜?br> List定義方式

var l1 = ['aaa','bbbb','cccc'];
var l2 = <String>[];
Maps(字典)

通常來(lái)說(shuō)叉存,Map 是一個(gè)鍵值對(duì)相關(guān)的對(duì)象码俩。 鍵和值可以是任何類(lèi)型的對(duì)象。每個(gè) 鍵只出現(xiàn)一次歼捏, 而一個(gè)值則可以出現(xiàn)多次
Map定義方式

var person = {
    "name":"張三",
    "age":20,
    "work":["程序員","送外賣(mài)"]
};
print(person["name"]);

var p = new Map();
p["name"] = "李四";
p["age"] = 22;
p["work"] = ["程序員","送外賣(mài)"];
print(p);
類(lèi)型判斷
var str=123;
if(str is String) {
  print('是string類(lèi)型');
}
else if(str is int) {
  print('int');
} else {
  print('其他類(lèi)型');
}

6 運(yùn)算符 條件判斷 類(lèi)型轉(zhuǎn)換

算術(shù)運(yùn)算符

加減乘除取余取整

int a = 13;
int b = 5;
print(a + b);   //加
print(a - b);   //減
print(a * b);   //乘
print(a / b);   //除
print(a % b);   //取余
print(a ~/ b);  //取整

++ --
表示自增 自減 1
在賦值運(yùn)算里面 如果++ -- 寫(xiě)在前面 這時(shí)候先運(yùn)算 再賦值稿存,如果++ --寫(xiě)在后面 先賦值后運(yùn)行運(yùn)算

var a = 10;
var b = a--;
print(a);  //9
print(b);  //10

var a = 10;
var b = ++a;
print(a);  //11
print(b);  //11
關(guān)系運(yùn)算符
int a = 5;
int b = 3;
print(a == b);   //判斷是否相等
print(a != b);   //判斷是否不等
print(a > b);    //判斷是否大于
print(a < b);    //判斷是否小于
print(a >= b);   //判斷是否大于等于
print(a <= b);   //判斷是否小于等于
邏輯運(yùn)算符

! 取反

bool flag = false;
print(!flag);

&& 并且: 全部為true的話(huà)值為true 否則值為false

bool a = true;
bool b = true;
print(a && b);

|| 或者:全為false的話(huà)值為false 否則值為true

bool a = false;
bool b = false;
print(a || b);
賦值運(yùn)算符

基礎(chǔ)賦值運(yùn)算符 = ??=

int a = 10;
int b = 3;
print(a);
int c = a + b;   //從右向左

int b;
b ??= 23;   // 表示如果b為空的話(huà)把 23賦值給b
print(b);

復(fù)合賦值運(yùn)算符 += -= *= /= %= ~/=

var a = 13;
a += 10;   //表示 a = a + 10
print(a);
條件表達(dá)式

if else switch case

// 判斷一個(gè)人的成績(jī) 如果大于60 顯示及格   如果大于 70顯示良好  如果大于90顯示優(yōu)秀
var score = 41;
if(score > 90) {
  print('優(yōu)秀');
} else if(score > 70) {
  print('良好');
} else if(score >= 60) {
  print('及格');
} else {
  print('不及格');
}

var sex = "女";
switch(sex) {
  case "男":
       print('性別是男');
       break;
  case "女":
       print('性別是女');
       break;
  default:
       print('傳入?yún)?shù)錯(cuò)誤');
       break;
  }

三目運(yùn)算符

bool flag = false;
String c = flag ? '我是true' : '我是false';
print(c);

?? 運(yùn)算符

var a = 22;
var b = a ?? 10;
print(b);
類(lèi)型轉(zhuǎn)換

Number與String類(lèi)型之間的轉(zhuǎn)換
Number類(lèi)型轉(zhuǎn)換成String類(lèi)型 toString()
String類(lèi)型轉(zhuǎn)成Number類(lèi)型 int.parse()

String str = '123';
var myNum = int.parse(str);
print(myNum is int);

String str = '123.1';
var myNum = double.parse(str);
print(myNum is double);

//報(bào)錯(cuò)
String price = '';
var myNum = double.parse(price);
print(myNum);
print(myNum is double);

// try  ... catch
String price = '';
try {
    var myNum=double.parse(price);
    print(myNum);
} catch(err) {
    print(0);
} 

var myNum = 12;
var str = myNum.toString();
print(str is String);

其他類(lèi)型轉(zhuǎn)換成Booleans類(lèi)型
isEmpty:判斷字符串是否為空

var str = '';
if(str.isEmpty) {
  print('str空');
} else {
  print('str不為空');
}

var myNum;
if(myNum == 0) {
   print('0');
} else {
  print('非0');
}

var myNum;
if(myNum == null) {
   print('空');
} else {
  print('非空');
}

var myNum = 0/0;
print(myNum);
if(myNum.isNaN) {
  print('NaN');
}

7 循環(huán)遍歷

for循環(huán)

基本語(yǔ)法
第一步,聲明變量int i = 1;
第二步瞳秽,判斷i <=100
第三步瓣履,print(i);
第四步,i++
第五步 從第二步再來(lái)练俐,直到判斷為false

for (int i = 1; i <= 100; i++) {   
     print(i);
}
 
//打印List  ['張三','李四','王五'] 里面的內(nèi)容
var list = ['張三','李四','王五'];
for(var i = 0; i < list.length; i++) {
  print(list[i]);
}
while循環(huán)

語(yǔ)法格式:
while(表達(dá)式/循環(huán)條件){
}

do{
語(yǔ)句/循環(huán)體
}while(表達(dá)式/循環(huán)條件);
注意: 1袖迎、最后的分號(hào)不要忘記
2、循環(huán)條件中使用的變量需要經(jīng)過(guò)初始化
3腺晾、循環(huán)體中燕锥,應(yīng)有結(jié)束循環(huán)的條件,否則會(huì)造成死循環(huán)悯蝉。

//求1+2+3+4 ...+100的和
int i = 1;
var sum = 0;
while(i <= 100) {
   sum += i;
   i++;
}
print(sum);

int i = 1;
var sum = 0;
do{
  sum += i;
  i++;
}while(i <= 100);
print(sum);
break和continue

break語(yǔ)句功能:
1归形、在switch語(yǔ)句中使流程跳出switch結(jié)構(gòu)。
2鼻由、在循環(huán)語(yǔ)句中使流程跳出當(dāng)前循環(huán),遇到break 循環(huán)終止暇榴,后面代碼也不會(huì)執(zhí)行
強(qiáng)調(diào):
1、如果在循環(huán)中已經(jīng)執(zhí)行了break語(yǔ)句,就不會(huì)執(zhí)行循環(huán)體中位于break后的語(yǔ)句蕉世。
2蔼紧、在多層循環(huán)中,一個(gè)break語(yǔ)句只能向外跳出一層
break可以用在switch case中 也可以用在 for 循環(huán)和 while循環(huán)中

continue語(yǔ)句的功能:
【注】只能在循環(huán)語(yǔ)句中使用,使本次循環(huán)結(jié)束,即跳過(guò)循環(huán)體重下面尚未執(zhí)行的語(yǔ)句讨彼,接著進(jìn)行下次的是否執(zhí)行循環(huán)的判斷歉井。
continue可以用在for循環(huán)以及 while循環(huán)中,但是不建議用在while循環(huán)中哈误,不小心容易死循環(huán)

// 如果i等于4的話(huà)跳過(guò)
for(var i = 1; i <= 10; i++) {
   if(i == 4) {
      continue;  /*跳過(guò)當(dāng)前循環(huán)體 然后循環(huán)還會(huì)繼續(xù)執(zhí)行*/
   }
   print(i);
}
  
// 如果 i等于4的話(huà)跳出循環(huán)
for(var i = 1; i <= 10; i++) {
    if(i == 4) {
       break;  /*跳出循環(huán)體*/
    }
    print(i);
}

8 List

List里面常用的屬性和方法:

常用屬性

length 長(zhǎng)度
reversed 翻轉(zhuǎn)
isEmpty 是否為空
isNotEmpty 是否不為空
var myList = ['香蕉','蘋(píng)果','西瓜'];
print(myList.length);
print(myList.isEmpty);
print(myList.isNotEmpty);
print(myList.reversed); //對(duì)列表倒序排序
var newMyList = myList.reversed.toList();
print(newMyList);

常用方法

add 增加
addAll 拼接數(shù)組
indexOf 查找 傳入具體值
remove 刪除 傳入具體值
removeAt 刪除 傳入索引值
fillRange 修改
insert(index,value); 指定位置插入
insertAll(index,list) 指定位置插入List
toList() 其他類(lèi)型轉(zhuǎn)換成List
join() List轉(zhuǎn)換成字符串
split() 字符串轉(zhuǎn)化成List
forEach
map
where
any
every

// List里面的方法:
var myList = ['香蕉','蘋(píng)果','西瓜'];
myList.add('桃子');   //增加數(shù)據(jù)  增加一個(gè)
myList.addAll(['桃子','葡萄']);  //拼接數(shù)組
print(myList);
print(myList.indexOf('蘋(píng)x果'));    //indexOf查找數(shù)據(jù) 查找不到返回-1  查找到返回索引值
myList.remove('西瓜');
myList.removeAt(1);
print(myList);
  
var myList = ['香蕉','蘋(píng)果','西瓜'];
myList.fillRange(1, 2, 'aaa');  //修改
myList.fillRange(1, 3, 'aaa');  
myList.insert(1, 'aaa');      //插入  一個(gè)
myList.insertAll(1, ['aaa', 'bbb']);  //插入 多個(gè)
print(myList);

var myList = ['香蕉','蘋(píng)果','西瓜'];
var str = myList.join('-');   //list轉(zhuǎn)換成字符串
print(str);
print(str is String);  //true

var str = '香蕉-蘋(píng)果-西瓜';
var list = str.split('-');
print(list);
print(list is List);

9 Set

用它最主要的功能就是去除數(shù)組重復(fù)內(nèi)容
Set是沒(méi)有順序且不能重復(fù)的集合,所以不能通過(guò)索引去獲取值

var s = new Set();
s.add('香蕉');
s.add('蘋(píng)果');
s.add('蘋(píng)果');
print(s);   // {香蕉, 蘋(píng)果}
print(s.toList()); 

var myList = ['香蕉','蘋(píng)果','西瓜','香蕉','蘋(píng)果','香蕉','蘋(píng)果'];
var s = new Set();
s.addAll(myList);
print(s);
print(s.toList());

10 Map

映射(Map)是無(wú)序的鍵值對(duì):
常用屬性
keys 獲取所有的key值
values 獲取所有的value值
isEmpty 是否為空
isNotEmpty 是否不為空

Map person = {
    "name":"張三",
    "age":20
};

var m = new Map();
m["name"] = "李四";
print(person);
print(m);

Map person = {
    "name":"張三",
    "age":20,
    "sex":"男"
};
print(person.keys.toList());
print(person.values.toList());
print(person.isEmpty);
print(person.isNotEmpty);
常用方法

remove(key) 刪除指定key的數(shù)據(jù)
addAll({...}) 合并映射 給映射內(nèi)增加屬性
containsValue 查看映射內(nèi)的值 返回true/false
forEach
map
where
any
every

Map person = {
    "name":"張三",
    "age":20,
    "sex":"男"
};
person.addAll({
    "work":['敲代碼', '送外賣(mài)'],
    "height":160
});
print(person);
person.remove("sex");
print(person);
print(person.containsValue('張三'));

11 forEach map where any every

forEach
List myList = ['香蕉', '蘋(píng)果', '西瓜'];
for(var i = 0; i < myList.length; i++) {
    print(myList[i]);
}

for(var item in myList) {
    print(item);
}

myList.forEach((value) {
    print("$value");
});

var s = new Set();
s.addAll([1,222,333]);
s.forEach((value) => print(value));

Map person = {
    "name":"張三",
    "age":20
};
person.forEach((key,value){            
    print("$key---$value");
});
map
List myList = [1, 3, 4];      
var newList = myList.map((value) {
     return value * 2;
});
print(newList.toList());
where
List myList = [1, 3, 4, 5, 7, 8, 9];
var newList = myList.where((value) {
     return value > 5;
});
print(newList.toList());
any
List myList = [1, 3, 4, 5, 7, 8, 9];
var f = myList.any((value) {   //只要集合里面有滿(mǎn)足條件的就返回true
     return value > 5;
});
print(f);
every
List myList = [1, 3, 4, 5, 7, 8, 9];
var f = myList.every((value) {   //每一個(gè)都滿(mǎn)足條件返回true  否則返回false
     return value > 5;
});
print(f);

12 方法的定義 變量 方法的作用域

內(nèi)置方法/函數(shù)

print();

自定義方法

自定義方法的基本格式:
返回類(lèi)型 方法名稱(chēng)(參數(shù)1躏嚎,參數(shù)2,...){
方法體
return 返回值;
}

void printInfo(){
  print('我是一個(gè)自定義方法');
}

int getNum(){
  var myNum = 123;
  return myNum;
}

String printUserInfo(){
  return 'this is str';
}

List getList(){
  return ['111','2222','333'];
}

void main(){
  print('調(diào)用系統(tǒng)內(nèi)置的方法');
  printInfo();
  
  var n = getNum();
  print(n);
  
  print(printUserInfo());
  print(getList());
  print(getList());
  

  //演示方法的作用域
  void xxx(){
      aaa(){
          print(getList());
          print('aaa');
      }
      aaa();
  }

  // aaa();  錯(cuò)誤寫(xiě)法 
  xxx();  //調(diào)用方法
}

13 方法傳參 蜜自、可選參數(shù)、默認(rèn)參數(shù)卢佣、命名參數(shù) 重荠、方法作為參數(shù)

方法傳參
// 定義一個(gè)方法 求1到這個(gè)數(shù)的所有數(shù)的和      60    1+2+3+。虚茶。戈鲁。+60
int sumNum(int n){
  var sum=0;
  for(var i = 1; i <= n; i++){
    sum+=i;
  }
  return sum;
} 
var n1 = sumNum(5);
print(n1);
var n2 = sumNum(100);
print(n2);

// 定義一個(gè)方法然后打印用戶(hù)信息
String printUserInfo(String username, int age){  //行參
  return "姓名:$username---年齡:$age";
}
print(printUserInfo('張三',20)); //實(shí)參
可選參數(shù)
String printUserInfo(String username, [int age]){  //行參
  if(age != null){
    return "姓名:$username---年齡:$age";
  }
  return "姓名:$username---年齡保密";
}
print(printUserInfo('張三', 21)); //實(shí)參
print(printUserInfo('張三'));
默認(rèn)參數(shù)
String printUserInfo(String username, [String sex = '男', int age]){  //行參
  if(age != null){
    return "姓名:$username---性別:$sex--年齡:$age";
  }
  return "姓名:$username---性別:$sex--年齡保密";
}
print(printUserInfo('張三'));
print(printUserInfo('小李', '女'));
print(printUserInfo('小李', '女', 30));
命名參數(shù)
String printUserInfo(String username, {int age, String sex = '男'}){  //行參
  if(age != null){
    return "姓名:$username---性別:$sex--年齡:$age";
  }
  return "姓名:$username---性別:$sex--年齡保密";
}
print(printUserInfo('張三', age:20, sex:'未知'));
方法作為參數(shù)
var fn = () {
  print('我是一個(gè)匿名方法');
};      
fn();

//方法
fn1(){
  print('fn1');
}

//方法
fn2(fn){
  fn();
}

//方法傳參調(diào)用fn2這個(gè)方法 把fn1這個(gè)方法當(dāng)做參數(shù)傳入
fn2(fn1);

14 箭頭函數(shù) 函數(shù)的相互調(diào)用

箭頭函數(shù)
/*需求:使用forEach打印下面List里面的數(shù)據(jù)*/
List list = ['蘋(píng)果', '香蕉', '西瓜'];
list.forEach((value){
  print(value);
});

list.forEach((value) => print(value));

list.forEach((value) => {
  print(value)
});


/*需求:修改下面List里面的數(shù)據(jù)仇参,讓數(shù)組中大于2的值乘以2*/
List list = [4, 1, 2, 3, 4];
var newList = list.map((value){
  if(value > 2){
    return value * 2;
  }
  return value;
});
print(newList.toList());

var newList = list.map((value) => value > 2 ? value * 2 : value);
print(newList.toList());
函數(shù)的相互調(diào)用
/*
需求:1、定義一個(gè)方法isEvenNumber來(lái)判斷一個(gè)數(shù)是否是偶數(shù)  
     2婆殿、定義一個(gè)方法打印1-n以?xún)?nèi)的所有偶數(shù)
*/
// 定義一個(gè)方法isEvenNumber來(lái)判斷一個(gè)數(shù)是否是偶數(shù)  
bool isEvenNumber(int n){
  if(n % 2 == 0){
    return true;
  }
  return false;
}

printNum(int n){
  for(var i = 1; i <= n; i++){
    if(isEvenNumber(i)){
      print(i);
    }
  }
}
printNum(10);

15 閉包

1诈乒、全局變量特點(diǎn): 全局變量常駐內(nèi)存、全局變量污染全局
2婆芦、局部變量的特點(diǎn): 不常駐內(nèi)存會(huì)被垃圾機(jī)制回收怕磨、不會(huì)污染全局
想實(shí)現(xiàn)的功能:1.常駐內(nèi)存 2.不污染全局
產(chǎn)生了閉包, 閉包可以解決這個(gè)問(wèn)題.....
閉包: 函數(shù)嵌套函數(shù), 內(nèi)部函數(shù)會(huì)調(diào)用外部函數(shù)的變量或參數(shù), 變量或參數(shù)不會(huì)被系統(tǒng)回收(不會(huì)釋放內(nèi)存)
閉包的寫(xiě)法: 函數(shù)嵌套函數(shù),并return 里面的函數(shù)消约,這樣就形成了閉包肠鲫。

/*全局變量*/
var a = 123;

void main(){
  print(a);
  fn(){
    a++;
    print(a);
  }
  fn();
  fn();
  fn();

  // 局部變量
  printInfo(){
    var myNum = 123;
    myNum++;
    print(myNum);
  }
  printInfo();
  printInfo();
  printInfo();
  
  // 閉包
  fn(){
    var a = 123;  /*不會(huì)污染全局   常駐內(nèi)存*/
    return(){           
      a++;          
      print(a);
     };        
  }     
  var b = fn(); 
  b();
  b();
  b();
}

16 面向?qū)ο蟮慕榻B 以及內(nèi)置對(duì)象

面向?qū)ο缶幊?OOP)的三個(gè)基本特征

封裝
封裝是對(duì)象和類(lèi)概念的主要特性。封裝或粮,把客觀事物封裝成抽象的類(lèi)导饲,并且把自己的部分屬性和方法提供給其他對(duì)象調(diào)用, 而一部分屬性和方法則隱藏。
繼承
面向?qū)ο缶幊?(OOP) 語(yǔ)言的一個(gè)主要功能就是“繼承”氯材。繼承是指這樣一種能力:它可以使用現(xiàn)有類(lèi)的功能渣锦,并在無(wú)需重新編寫(xiě)原來(lái)的類(lèi)的情況下對(duì)這些功能進(jìn)行擴(kuò)展。
多態(tài)
允許將子類(lèi)類(lèi)型的指針賦值給父類(lèi)類(lèi)型的指針, 同一個(gè)函數(shù)調(diào)用會(huì)有不同的執(zhí)行效果 浓体。
Dart所有的東西都是對(duì)象泡挺,所有的對(duì)象都繼承自O(shè)bject類(lèi)。
Dart是一門(mén)使用類(lèi)和單繼承的面向?qū)ο笳Z(yǔ)言命浴,所有的對(duì)象都是類(lèi)的實(shí)例娄猫,并且所有的類(lèi)都是Object的子類(lèi)
一個(gè)類(lèi)通常由屬性和方法組成。

List list = new List();
list.isEmpty;
list.add('香蕉');
list.add('香蕉1');

Map m = new Map();
m["username"] = "張三";
m.addAll({"age":20});
m.isEmpty;

Object a = 123;
Object v = true;
print(a);
print(v);

17 創(chuàng)建自定義類(lèi)使用類(lèi)

Dart是一門(mén)使用類(lèi)和單繼承的面向?qū)ο笳Z(yǔ)言生闲,所有的對(duì)象都是類(lèi)的實(shí)例媳溺,并且所有的類(lèi)都是Object的子類(lèi)

class Person {
  String name = "張三";
  int age = 23;
  void getInfo(){
    
      // print("$name----$age");
      print("${this.name}----${this.age}");
  }
  void setInfo(int age){
    this.age = age;
  }
}
void main(){

  // 實(shí)例化
  Person p1 = new Person();
  print(p1.name);
  p1.setInfo(28);
  p1.getInfo();
}
自定義類(lèi)的默認(rèn)構(gòu)造函數(shù)
class Person {
  String name = '張三';
  int age = 20; 
  
  //默認(rèn)構(gòu)造函數(shù)
  Person(){
    print('這是構(gòu)造函數(shù)里面的內(nèi)容  這個(gè)方法在實(shí)例化的時(shí)候觸發(fā)');
  }
  void printInfo(){   
    print("${this.name}----${this.age}");
  }
}

// 張三  李四  王五
class Person {
  String name;
  int age; 
  
  //默認(rèn)構(gòu)造函數(shù)
  Person(String name, int age){
    this.name = name;
    this.age = age;
  }
  void printInfo(){   
    print("${this.name}----${this.age}");
  }
}

class Person {
  String name;
  int age; 
  
  //默認(rèn)構(gòu)造函數(shù)的簡(jiǎn)寫(xiě)
  Person(this.name, this.age);
  void printInfo(){   
    print("${this.name}----${this.age}");
  }
}

void main(){
  Person p1 = new Person('張三',20);
  p1.printInfo();

  Person p2 = new Person('李四',25);
  p2.printInfo();
}
自定義類(lèi)的命名構(gòu)造函數(shù)

dart里面構(gòu)造函數(shù)可以寫(xiě)多個(gè)

class Person {
  String name;
  int age; 
  
  //默認(rèn)構(gòu)造函數(shù)的簡(jiǎn)寫(xiě)
  Person(this.name, this.age);
  
  Person.now(){
    print('我是命名構(gòu)造函數(shù)');
  }

  Person.setInfo(String name, int age){
    this.name = name;
    this.age = age;
  }

  void printInfo(){   
    print("${this.name}----${this.age}");
  }
}

void main(){
  var d = new DateTime.now();   //實(shí)例化DateTime調(diào)用它的命名構(gòu)造函數(shù)
  print(d);
  
  Person p1 = new Person('張三', 20);   //默認(rèn)實(shí)例化類(lèi)的時(shí)候調(diào)用的是 默認(rèn)構(gòu)造函數(shù)
  
  Person p1 = new Person.now();   //命名構(gòu)造函數(shù)
  
  Person p1 = new Person.setInfo('李四',30);
  p1.printInfo(); 
}
把類(lèi)單獨(dú)抽離成一個(gè)模塊
// 將Person類(lèi)文件Person.dart放到lib文件夾里面
import 'lib/Person.dart';

void main(){
  Person p1 = new Person.setInfo('李四1', 30);
  p1.printInfo(); 
}
私有方法和私有屬性

Dart和其他面向?qū)ο笳Z(yǔ)言不一樣,Data中沒(méi)有 public private protected這些訪問(wèn)修飾符合
我們可以使用_把一個(gè)屬性或者方法定義成私有碍讯。

class Animal {
  String _name;   //私有屬性
  int age; 
  
  //默認(rèn)構(gòu)造函數(shù)的簡(jiǎn)寫(xiě)
  Animal(this._name, this.age);

  void printInfo(){   
    print("${this._name}----${this.age}");
  }

  String getName(){ 
    return this._name;
  } 
  void _run(){
    print('這是一個(gè)私有方法');
  }

  execRun(){
    this._run();  //類(lèi)里面方法的相互調(diào)用
  }
}

import 'lib/Animal.dart';

void main(){
 
 Animal a = new Animal('小狗', 3);
 print(a.getName());
 a.execRun();   //間接的調(diào)用私有方法
}
類(lèi)中的getter和setter修飾符的用法
class Rect {
  int height;
  int width;
  
  getArea(){
    return this.height * this.width;
  } 
}

class Rect {
  num height;
  num width; 
  
  Rect(this.height, this.width);
  area(){
    return this.height * this.width;
  }
}

void main(){
  Rect r = new Rect(10, 4);
  print("面積:${r.area()}");   
}

class Rect {
  num height;
  num width;   
  Rect(this.height, this.width);
  get area{
    return this.height * this.width;
  }
}

void main(){
  Rect r = new Rect(10, 2);
  print("面積:${r.area}");      //注意調(diào)用直接通過(guò)訪問(wèn)屬性的方式訪問(wèn)area
}

class Rect {
  num height;
  num width; 
  
  Rect(this.height, this.width);
  get area{
    return this.height * this.width;
  }
  set areaHeight(value){
    this.height = value;
  }
}

void main(){
  Rect r = new Rect(10, 4);
  // print("面積:${r.area()}");   
  r.areaHeight = 6;
  print(r.area);
}
類(lèi)中的初始化列表

我們也可以在構(gòu)造函數(shù)體運(yùn)行之前初始化實(shí)例變量

class Rect {
  int height;
  int width;
  Rect():height = 2, width = 10{
    print("${this.height}---${this.width}");
  }
  getArea(){
    return this.height * this.width;
  } 
}

void main(){
  Rect r = new Rect();
  print(r.getArea()); 
}
類(lèi)中的靜態(tài)成員 靜態(tài)方法

Dart中的靜態(tài)成員:
1悬蔽、使用static 關(guān)鍵字來(lái)實(shí)現(xiàn)類(lèi)級(jí)別的變量和函數(shù)
2、靜態(tài)方法不能訪問(wèn)非靜態(tài)成員捉兴,非靜態(tài)方法可以訪問(wèn)靜態(tài)成員

class Person {
  static String name = '張三';
  static void show() {
    print(name);
  }
}

main(){
  print(Person.name);
  Person.show();  
}

class Person {
  static String name = '張三';
  int age = 20;
  
  static void show() {
    print(name);
  }
  
  void printInfo(){  /*非靜態(tài)方法可以訪問(wèn)靜態(tài)成員以及非靜態(tài)成員*/
    print(name);  //訪問(wèn)靜態(tài)屬性
    print(this.age);  //訪問(wèn)非靜態(tài)屬性
    show();   //調(diào)用靜態(tài)方法
  }
  
  static void printUserInfo(){//靜態(tài)方法
    print(name);   //靜態(tài)屬性
    show();        //靜態(tài)方法
    
    // print(this.age);     //靜態(tài)方法沒(méi)法訪問(wèn)非靜態(tài)的屬性
    // this.printInfo();    //靜態(tài)方法沒(méi)法訪問(wèn)非靜態(tài)的方法
    // printInfo();
  }
}

main(){
  print(Person.name);
  Person.show(); 
  
  Person p = new Person();
  p.printInfo(); 
  Person.printUserInfo();
}
對(duì)象操作符

? 條件運(yùn)算符 (了解)
as 類(lèi)型轉(zhuǎn)換
is 類(lèi)型判斷
.. 級(jí)聯(lián)操作 (連綴) (記住)

class Person {
  String name;
  num age;
  Person(this.name, this.age);
  void printInfo() {
    print("${this.name}---${this.age}");  
  }
}

main(){ 
  Person p;
  p?.printInfo();
  
  Person p = new Person('張三', 20);
  p?.printInfo();
  
  Person p = new Person('張三', 20);
  if(p is Person){
    p.name = "李四";
  } 
  p.printInfo();
  print(p is Object);

  var p1;
  p1 = '';
  p1 = new Person('張三1', 20);

    // // p1.printInfo();
    // (p1 as Person).printInfo();

  Person p1 = new Person('張三1', 20);
  p1.printInfo();
  p1.name = '張三222';
  p1.age = 40;
  p1.printInfo();
  
  Person p1 = new Person('張三1', 20);
  p1.printInfo();
  p1..name = "李四"
    ..age = 30
    ..printInfo();
}
類(lèi)的繼承-簡(jiǎn)單繼承

1蝎困、子類(lèi)使用extends關(guān)鍵詞來(lái)繼承父類(lèi)
2、子類(lèi)會(huì)繼承父類(lèi)里面可見(jiàn)的屬性和方法 但是不會(huì)繼承構(gòu)造函數(shù)
3倍啥、子類(lèi)能復(fù)寫(xiě)父類(lèi)的方法 getter和setter

class Person {
  String name = '張三';
  num age = 20; 
  void printInfo() {
    print("${this.name}---${this.age}");  
  } 
}

class Web extends Person {

}

main(){
  Web w = new Web();
  print(w.name);
  w.printInfo();
}
super關(guān)鍵詞的使用
class Person {
  String name;
  num age; 
  Person(this.name, this.age);
  void printInfo() {
    print("${this.name}---${this.age}");  
  }
}

class Web extends Person {
  Web(String name, num age) : super(name, age){

  }
}

main(){ 
  Person p = new Person('李四', 20);
  p.printInfo();

  Person p1 = new Person('張三', 20);
  p1.printInfo();

  Web w = new Web('張三', 12);
  w.printInfo();
}
實(shí)例化自類(lèi) 給父類(lèi)構(gòu)造函數(shù)傳參
class Person {
  String name;
  num age; 
  Person(this.name, this.age);
  Person.xxx(this.name, this.age);
  void printInfo() {
    print("${this.name}---${this.age}");  
  }
}

class Web extends Person {
  String sex;
  Web(String name, num age, String sex) : super.xxx(name, age){
    this.sex = sex;
  }
  run(){
   print("${this.name}---${this.age}--${this.sex}");  
  }
}

main(){ 
  Person p = new Person('李四', 20);
  p.printInfo();
  
  Person p1 = new Person('張三', 20);
  p1.printInfo();

  Web w = new Web('張三', 12, "男");
  w.printInfo();
  w.run();
}
實(shí)例化自類(lèi)給命名構(gòu)造函數(shù)傳參
class Person {
  String name;
  num age; 
  Person(this.name, this.age);
  Person.xxx(this.name, this.age);
  void printInfo() {
    print("${this.name}---${this.age}");  
  }
}

class Web extends Person {
  String sex;
  Web(String name, num age, String sex) : super.xxx(name, age){
    this.sex = sex;
  }
  run(){
   print("${this.name}---${this.age}--${this.sex}");  
  }
}

main(){ 
  Person p = new Person('李四', 20);
  p.printInfo();
  
  Person p1 = new Person('張三', 20);
  p1.printInfo();

  Web w = new Web('張三', 12, "男");
  w.printInfo();
  w.run();
}
覆寫(xiě)父類(lèi)的方法
class Person {
  String name;
  num age; 
  Person(this.name, this.age);
  void printInfo() {
    print("${this.name}---${this.age}");  
  }
  work(){
    print("${this.name}在工作...");
  }
}

class Web extends Person {
  Web(String name, num age) : super(name, age);
  run(){
    print('run');
  }
  
  //覆寫(xiě)父類(lèi)的方法
  @override       //可以寫(xiě)也可以不寫(xiě)  建議在覆寫(xiě)父類(lèi)方法的時(shí)候加上 @override 
  void printInfo(){
     print("姓名:${this.name}---年齡:${this.age}"); 
  }
  
  @override
  work(){
    print("${this.name}的工作是寫(xiě)代碼");
  }
}

main(){ 
  Web w = new Web('李四', 20);
  w.printInfo();
  w.work();
}
自類(lèi)里面調(diào)用父類(lèi)的方法
class Person {
  String name;
  num age; 
  Person(this.name, this.age);
  void printInfo() {
    print("${this.name}---${this.age}");  
  }
  work(){
    print("${this.name}在工作...");
  }
}

class Web extends Person {
  Web(String name, num age) : super(name, age);

  run(){
    print('run');
    super.work();  //自類(lèi)調(diào)用父類(lèi)的方法
  }
  
  //覆寫(xiě)父類(lèi)的方法
  @override       //可以寫(xiě)也可以不寫(xiě)  建議在覆寫(xiě)父類(lèi)方法的時(shí)候加上 @override 
  void printInfo(){
     print("姓名:${this.name}---年齡:${this.age}"); 
  }
}

main(){ 
  Web w = new Web('李四', 20);
  w.printInfo();
  w.run();
}
抽象類(lèi)

抽象類(lèi)主要用于定義標(biāo)準(zhǔn)禾乘,子類(lèi)可以繼承抽象類(lèi),也可以實(shí)現(xiàn)抽象類(lèi)接口虽缕。
1始藕、抽象類(lèi)通過(guò)abstract 關(guān)鍵字來(lái)定義
2、抽象方法不能用abstract聲明,沒(méi)有方法體的方法我們稱(chēng)為抽象方法伍派。
3江耀、如果子類(lèi)繼承抽象類(lèi)必須得實(shí)現(xiàn)里面的抽象方法
4、如果把抽象類(lèi)當(dāng)做接口實(shí)現(xiàn)的話(huà)必須得實(shí)現(xiàn)抽象類(lèi)里面定義的所有屬性和方法诉植。
5祥国、抽象類(lèi)不能被實(shí)例化,只有繼承它的子類(lèi)可以
extends抽象類(lèi) 和 implements的區(qū)別:
1倍踪、如果要復(fù)用抽象類(lèi)里面的方法系宫,并且要用抽象方法約束自類(lèi)的話(huà)我們就用extends繼承抽象類(lèi)
2、如果只是把抽象類(lèi)當(dāng)做標(biāo)準(zhǔn)的話(huà)我們就用implements實(shí)現(xiàn)抽象類(lèi)
案例:定義一個(gè)Animal 類(lèi)要求它的子類(lèi)必須包含eat方法

abstract class Animal {
  eat();   //抽象方法
  run();   //抽象方法  
  printInfo(){
    print('我是一個(gè)抽象類(lèi)里面的普通方法');
  }
}

class Dog extends Animal {
  @override
  eat() {
     print('小狗在吃骨頭');
  }

  @override
  run() {
    print('小狗在跑');
  }  
}
class Cat extends Animal {
  @override
  eat() {
    print('小貓?jiān)诔岳鲜?);
  }

  @override
  run() {
    print('小貓?jiān)谂?);
  }
}

main(){
  Dog d = new Dog();
  d.eat();
  d.printInfo();
  
  Cat c = new Cat();
  c.eat();
  c.printInfo();

  // Animal a=new Animal();   //抽象類(lèi)沒(méi)法直接被實(shí)例化
}

18 多態(tài)

允許將子類(lèi)類(lèi)型的指針賦值給父類(lèi)類(lèi)型的指針, 同一個(gè)函數(shù)調(diào)用會(huì)有不同的執(zhí)行效果 建车。
子類(lèi)的實(shí)例賦值給父類(lèi)的引用扩借。
多態(tài)就是父類(lèi)定義一個(gè)方法不去實(shí)現(xiàn),讓繼承他的子類(lèi)去實(shí)現(xiàn)缤至,每個(gè)子類(lèi)有不同的表現(xiàn)潮罪。

abstract class Animal {
  eat();   // 抽象方法 
}

class Dog extends Animal {
  @override
  eat() {
     print('小狗在吃骨頭');
  }
  run(){
    print('run');
  }
}

class Cat extends Animal {
  @override
  eat() {   
    print('小貓?jiān)诔岳鲜?);
  }
  run(){
    print('run');
  }
}

main(){
  Dog d = new Dog();
  d.eat();
  d.run();

  Cat c = new Cat();
  c.eat();

  Animal d = new Dog();
  d.eat();

  Animal c = new Cat();
  c.eat();
}

19 接口

和Java一樣,dart也有接口领斥,但是和Java還是有區(qū)別的嫉到。
首先,dart的接口沒(méi)有interface關(guān)鍵字定義接口月洛,而是普通類(lèi)或抽象類(lèi)都可以作為接口被實(shí)現(xiàn)何恶。
同樣使用implements關(guān)鍵字進(jìn)行實(shí)現(xiàn)。
但是dart的接口有點(diǎn)奇怪嚼黔,如果實(shí)現(xiàn)的類(lèi)是普通類(lèi)细层,會(huì)將普通類(lèi)和抽象中的屬性和方法全部需要覆寫(xiě)一遍。
而因?yàn)槌橄箢?lèi)可以定義抽象方法唬涧,普通類(lèi)不可以疫赎,所以一般如果要實(shí)現(xiàn)像Java接口那樣的方式,一般會(huì)使用抽象類(lèi)碎节。
建議使用抽象類(lèi)定義接口捧搞。
定義一個(gè)DB庫(kù) 支持 mysql mssql mongodb
mysql mssql mongodb三個(gè)類(lèi)里面都有同樣的方法

abstract class Db {   // 當(dāng)做接口   接口:就是約定 、規(guī)范
    String uri;       // 數(shù)據(jù)庫(kù)的鏈接地址
    add(String data);
    save();
    delete();
}

class Mysql implements Db {
  
  @override
  String uri;

  Mysql(this.uri);

  @override
  add(data) {
    print('這是mysql的add方法'+data);
  }

  @override
  delete() {
    return null;
  }

  @override
  save() {
    return null;
  }

  remove() {
      
  }
}

class MsSql implements Db {
  @override
  String uri;
  @override
  add(String data) {
    print('這是mssql的add方法'+data);
  }

  @override
  delete() {
    return null;
  }

  @override
  save() {
    return null;
  }
}

main() {
  Mysql mysql = new Mysql('xxxxxx');
  mysql.add('1243214');
}

20 implements實(shí)現(xiàn)多個(gè)接口

abstract class A {
  String name;
  printA();
}

abstract class B {
  printB();
}

class C implements A, B {  
  @override
  String name; 
  
  @override
  printA() {
    print('printA');
  }
  
  @override
  printB() {
    return null;
  }
}

void main(){
  C c = new C();
  c.printA();
}

21 mixins

mixins的中文意思是混入狮荔,就是在類(lèi)中混入其他功能胎撇。
可以使用mixins實(shí)現(xiàn)類(lèi)似多繼承的功能
因?yàn)閙ixins使用的條件,隨著Dart版本一直在變殖氏,這里講的是Dart2.x中使用mixins的條件:
1创坞、作為mixins的類(lèi)只能繼承自O(shè)bject,不能繼承其他類(lèi)
2受葛、作為mixins的類(lèi)不能有構(gòu)造函數(shù)
3、一個(gè)類(lèi)可以mixins多個(gè)mixins類(lèi)
4、mixins絕不是繼承总滩,也不是接口纲堵,而是一種全新的特性

class A {
  String info = "this is A";
  void printA() {
    print("A");
  }
}

class B {
  void printB() {
    print("B");
  }
}

class C with A, B {

}

void main() {
  var c = new C();  
  c.printA();
  c.printB();
  print(c.info);
}

class Person {
  String name;
  num age;
  Person(this.name, this.age);
  printInfo() {
    print('${this.name}----${this.age}');
  }
  void run() {
    print("Person Run");
  }
}

class A {
  String info = "this is A";
  void printA() {
    print("A");
  }
  void run() {
    print("A Run");
  }
}

class B {  
  void printB() {
    print("B");
  }
  void run() {
    print("B Run");
  }
}

class C extends Person with B, A {
  C(String name, num age) : super(name, age);
  
}

void main() {  
  var c = new C('張三', 20);  
  c.printInfo();
  c.printB();
  print(c.info);
  c.run();
}

mixins的實(shí)例類(lèi)型是什么?
很簡(jiǎn)單闰渔,mixins的類(lèi)型就是其超類(lèi)的子類(lèi)型席函。

class A {
  String info = "this is A";
  void printA() {
    print("A");
  }
}

class B {
  void printB() {
    print("B");
  }
}

class C with A, B {
  
}

void main() {  
  var c = new C();  
  print(c is C);    //true
  print(c is A);    //true
  print(c is B);    //true
  
  var a = new A();
  print(a is Object);
}

22 泛型

泛型就是解決 類(lèi) 接口 方法的復(fù)用性、以及對(duì)不特定數(shù)據(jù)類(lèi)型的支持(類(lèi)型校驗(yàn))

泛型方法
// 只能返回string類(lèi)型的數(shù)據(jù)
String getData(String value) {
  return value;
}
  
// 同時(shí)支持返回 string類(lèi)型 和int類(lèi)型  (代碼冗余)
String getData1(String value) {
  return value;
}

int getData2(int value) {
  return value;
}

// 同時(shí)返回 string類(lèi)型 和number類(lèi)型       不指定類(lèi)型可以解決這個(gè)問(wèn)題
getData(value) {
  return value;
}

// 不指定類(lèi)型放棄了類(lèi)型檢查冈涧。我們現(xiàn)在想實(shí)現(xiàn)的是傳入什么 返回什么茂附。比如:傳入number 類(lèi)型必須返回number類(lèi)型  傳入 string類(lèi)型必須返回string類(lèi)型
getData<T>(T value) {
  return value;
}

void main() {
  print(getData(21));
  print(getData('xxx'));
  getData<String>('你好');
  print(getData<int>(12));
}
集合List 泛型類(lèi)的用法

案例:把下面類(lèi)轉(zhuǎn)換成泛型類(lèi),要求List里面可以增加int類(lèi)型的數(shù)據(jù)督弓,也可以增加String類(lèi)型的數(shù)據(jù)营曼。但是每次調(diào)用增加的類(lèi)型要統(tǒng)一

class PrintClass<T> {
      List list = new List<T>();
      void add(T value){
          this.list.add(value);
      }
      void printInfo() {          
          for(var i = 0; i < this.list.length; i++) {
            print(this.list[i]);
          }
      }
 }

main() {  
  PrintClass p = new PrintClass<int>();
  p.add(12);
  p.add(23);
  p.printInfo();

  List list=new List<String>();
  // // list.add(12);  //錯(cuò)誤的寫(xiě)法
  list.add('你好');
  list.add('你好1');
  print(list);

  List list=new List<int>();
  // // list.add("你好");  //錯(cuò)誤寫(xiě)法
  list.add(12); 
  print(list);
}
泛型接口

實(shí)現(xiàn)數(shù)據(jù)緩存的功能:有文件緩存、和內(nèi)存緩存愚隧。內(nèi)存緩存和文件緩存按照接口約束實(shí)現(xiàn)蒂阱。
1、定義一個(gè)泛型接口 約束實(shí)現(xiàn)它的子類(lèi)必須有g(shù)etByKey(key) 和 setByKey(key,value)
2狂塘、要求setByKey的時(shí)候的value的類(lèi)型和實(shí)例化子類(lèi)的時(shí)候指定的類(lèi)型一致

abstract class Cache<T> {
  getByKey(String key);
  void setByKey(String key, T value);
}

class FlieCache<T> implements Cache<T> {
  @override
  getByKey(String key) {    
    return null;
  }

  @override
  void setByKey(String key, T value) {
   print("我是文件緩存 把key=${key}  value=${value}的數(shù)據(jù)寫(xiě)入到了文件中");
  }
}

class MemoryCache<T> implements Cache<T> {
  @override
  getByKey(String key) {   
    return null;
  }

  @override
  void setByKey(String key, T value) {
       print("我是內(nèi)存緩存 把key=${key}  value=${value} -寫(xiě)入到了內(nèi)存中");
  }
}
void main(){
  MemoryCache m = new MemoryCache<String>();
  m.setByKey('index', '首頁(yè)數(shù)據(jù)');
  MemoryCache m = new MemoryCache<Map>();
  m.setByKey('index', {"name":"張三", "age":20});
}

23 庫(kù)

前面介紹Dart基礎(chǔ)知識(shí)的時(shí)候基本上都是在一個(gè)文件里面編寫(xiě)Dart代碼的录煤,但實(shí)際開(kāi)發(fā)中不可能這么寫(xiě),模塊化很重要荞胡,所以這就需要使用到庫(kù)的概念妈踊。
在Dart中,庫(kù)的使用時(shí)通過(guò)import關(guān)鍵字引入的泪漂。
library指令可以創(chuàng)建一個(gè)庫(kù)廊营,每個(gè)Dart文件都是一個(gè)庫(kù),即使沒(méi)有使用library指令來(lái)指定窖梁。

Dart中的庫(kù)主要有三種

1赘风、我們自定義的庫(kù)
import 'lib/xxx.dart';
2、系統(tǒng)內(nèi)置庫(kù)
import 'dart:math';
import 'dart:io';
import 'dart:convert';
3纵刘、Pub包管理系統(tǒng)中的庫(kù)
https://pub.dev/packages
https://pub.flutter-io.cn/packages
https://pub.dartlang.org/flutter/
1邀窃、需要在自己項(xiàng)目根目錄新建一個(gè)pubspec.yaml
2、在pubspec.yaml文件 然后配置名稱(chēng) 假哎、描述瞬捕、依賴(lài)等信息
3、然后運(yùn)行 pub get 獲取包下載到本地
4舵抹、項(xiàng)目中引入庫(kù) import 'package:http/http.dart' as http; 看文檔使用

導(dǎo)入自己本地庫(kù)
import 'lib/Animal.dart';
main() {
  var a = new Animal('小黑狗', 20);
  print(a.getName());
}
導(dǎo)入系統(tǒng)內(nèi)置庫(kù)
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對(duì)象
  var httpClient = new HttpClient();  
  
  // 2、創(chuàng)建Uri對(duì)象
  var uri = new Uri.http('news-at.zhihu.com','/api/3/stories/latest');
  
  // 3惧蛹、發(fā)起請(qǐng)求扇救,等待請(qǐng)求
  var request = await httpClient.getUrl(uri);
  
  // 4刑枝、關(guān)閉請(qǐng)求,等待響應(yīng)
  var response = await request.close();
  
  // 5迅腔、解碼響應(yīng)的內(nèi)容
  return await response.transform(utf8.decoder).join();
}

async和await
這兩個(gè)關(guān)鍵字的使用只需要記住兩點(diǎn):
只有async方法才能使用await關(guān)鍵字調(diào)用方法
如果調(diào)用別的async方法必須使用await關(guān)鍵字
async是讓方法變成異步装畅。
await是等待異步方法執(zhí)行完成。

void main() async {
  var result = await testAsync();
  print(result);

}

// 異步方法
testAsync() async{
  return 'Hello async';
}
導(dǎo)入Pub包管理系統(tǒng)中的庫(kù)

pub包管理系統(tǒng):
1沧烈、從下面網(wǎng)址找到要用的庫(kù)
https://pub.dev/packages
https://pub.flutter-io.cn/packages
https://pub.dartlang.org/flutter/
2掠兄、創(chuàng)建一個(gè)pubspec.yaml文件,內(nèi)容如下

name: xxx
description: A new flutter module project.
dependencies:
  http: ^0.12.0+2
  date_format: ^1.0.6

3锌雀、配置dependencies
4蚂夕、運(yùn)行pub get 獲取遠(yuǎn)程庫(kù)
5、看文檔引入庫(kù)使用

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

main() async {
  var url = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1";
  
  // Await the http get response, then decode the json-formatted responce.
  var response = await http.get(url);
  if (response.statusCode == 200) {
    var jsonResponse = convert.jsonDecode(response.body);
    print(jsonResponse);
  } else {
    print("Request failed with status: ${response.statusCode}.");
  }
  print(formatDate(DateTime(1989, 2, 21), [yyyy, '*', mm, '*', dd]));
}
庫(kù)的重命名 沖突解決

沖突解決
當(dāng)引入兩個(gè)庫(kù)中有相同名稱(chēng)標(biāo)識(shí)符的時(shí)候腋逆,如果是java通常我們通過(guò)寫(xiě)上完整的包名路徑來(lái)指定使用的具體標(biāo)識(shí)符婿牍,甚至不用import都可以,但是Dart里面是必須import的闲礼。當(dāng)沖突的時(shí)候牍汹,可以使用as關(guān)鍵字來(lái)指定庫(kù)的前綴。如下例子所示:

import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
Element element1 = new Element(); // Uses Element from lib1.
lib2.Element element2 = new lib2.Element(); // Uses Element from lib2.

import 'lib/Person1.dart';
import 'lib/Person2.dart' as lib;
main(List<String> args) {
  Person p1 = new Person('張三', 20);
  p1.printInfo();

  lib.Person p2 = new lib.Person('李四', 20);
  p2.printInfo();
}
部分導(dǎo)入

如果只需要導(dǎo)入庫(kù)的一部分柬泽,有兩種模式:
模式一:只導(dǎo)入需要的部分慎菲,使用show關(guān)鍵字,如下例子所示:

import 'package:lib1/lib1.dart' show foo;

模式二:隱藏不需要的部分锨并,使用hide關(guān)鍵字露该,如下例子所示:

import 'package:lib2/lib2.dart' hide foo; 
//import 'lib/myMath.dart' show getAge;
import 'lib/myMath.dart' hide getName;

void main(){
//  getName();
  getAge();
}
延遲加載

也稱(chēng)為懶加載,可以在需要的時(shí)候再進(jìn)行加載第煮。
懶加載的最大好處是可以減少APP的啟動(dòng)時(shí)間解幼。
懶加載使用deferred as關(guān)鍵字來(lái)指定,如下例子所示:
當(dāng)需要使用的時(shí)候包警,需要使用loadLibrary()方法來(lái)加載:

import 'package:deferred/hello.dart' deferred as hello;
greet() async {
  await hello.loadLibrary();
  hello.printGreeting();
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撵摆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子害晦,更是在濱河造成了極大的恐慌特铝,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壹瘟,死亡現(xiàn)場(chǎng)離奇詭異鲫剿,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)稻轨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)灵莲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人殴俱,你說(shuō)我怎么就攤上這事政冻∶兜郑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵赠幕,是天一觀的道長(zhǎng)俄精。 經(jīng)常有香客問(wèn)我,道長(zhǎng)榕堰,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任嫌套,我火速辦了婚禮逆屡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘踱讨。我一直安慰自己魏蔗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布痹筛。 她就那樣靜靜地躺著莺治,像睡著了一般。 火紅的嫁衣襯著肌膚如雪帚稠。 梳的紋絲不亂的頭發(fā)上谣旁,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音滋早,去河邊找鬼榄审。 笑死,一個(gè)胖子當(dāng)著我的面吹牛杆麸,可吹牛的內(nèi)容都是我干的搁进。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼昔头,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼饼问!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起揭斧,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤莱革,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后未蝌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體驮吱,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年萧吠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了左冬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纸型,死狀恐怖拇砰,靈堂內(nèi)的尸體忽然破棺而出梅忌,到底是詐尸還是另有隱情,我是刑警寧澤除破,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布牧氮,位于F島的核電站,受9級(jí)特大地震影響瑰枫,放射性物質(zhì)發(fā)生泄漏踱葛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一光坝、第九天 我趴在偏房一處隱蔽的房頂上張望尸诽。 院中可真熱鬧,春花似錦盯另、人聲如沸性含。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)商蕴。三九已至,卻和暖如春芝发,著一層夾襖步出監(jiān)牢的瞬間绪商,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工后德, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留部宿,地道東北人们何。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓优构,卻偏偏與公主長(zhǎng)得像扔仓,于是被迫代替她去往敵國(guó)和親根盒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锣笨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容