DARTS技術,Dart 總結

 2023-12-25 阅读 29 评论 0

摘要:文章目錄1、Dart 介紹2、Dart 安裝3、知識點3.1、Dart介紹、Dart環境搭建、Dart開發工具3.2、變量、常量、命名規則、入口方法的兩種定義方式3.3、常用數據類型、字符串類型、數值類型、布爾類型、List集合類型、Maps類型3.4、運算符、條件判斷、類型轉換3.5、自增自減運算符

文章目錄

    • 1、Dart 介紹
    • 2、Dart 安裝
    • 3、知識點
      • 3.1、Dart介紹、Dart環境搭建、Dart開發工具
      • 3.2、變量、常量、命名規則、入口方法的兩種定義方式
      • 3.3、常用數據類型、字符串類型、數值類型、布爾類型、List集合類型、Maps類型
      • 3.4、運算符、條件判斷、類型轉換
      • 3.5、自增自減運算符、for、while、do...while循環、continue、break、多維列表循環
      • 3.6、集合類型List Set Map詳解 以及循環語句 forEach map where any every
      • 3.7、函數的定義 可選參數 默認參數 命名參數
      • 3.8、函數、箭頭函數 匿名函數 閉包等
      • 3.9、對象、類
      • 3.10、類 靜態成員 操作符 類的繼承
      • 3.11、抽象類 多態 以及接口
      • 3.12、一個類實現多個接口 以及Dart中的Mixins
      • 3.13、泛型、泛型方法 、泛型類、泛型接口
      • 3.14、庫 自定義庫、系統庫、第三方庫
    • 4、常見問題
      • 4.1、String和int互轉
      • 4.2、字符串(String)的相關方法
      • 4.3、JSON

1、Dart 介紹

一丶Dart 概述

  • Dart 是 Google 發布的一門開源編程語言
  • Dart 初期目標是稱為下一代的 web 開發語言
  • Dart 目前已可用于全平臺開發
  • Dart 是一門面向對象的編程語言

DARTS技術,二丶為什么使用Dart

  1. 高校
    Dart 語法清晰簡潔,工具簡單而強大。輸入檢測可幫助您盡早識別細微錯誤。Dart 擁有久經考驗的 核心庫 和一個已經擁有數以千計的 packages 生態系統

  2. 快速
    Dart 提供提前編譯優化,以在移動設備和 web 上實現可預測的高性能和快速啟動。

  3. 可移植
    Dart 可以編譯成 ARM 和 x86 代碼,因此 Dart 移動應用程序可以在 iOS,Android 及 更高版本上實現本地運行。對于 web 應用程序,Dart 可以轉化為 JavaScript。

  4. dart 菜鳥教程,易學
    Dart 是面向對象的編程語言,語法風格對于許多現有的開發人員來說都很熟悉。如果您已經了解C++,C# 或 Java,那么使用 Dart 也就是分分鐘的事情。

  5. 響應式
    Dart 可以便捷的進行響應式編程。由于快速對象分配和垃圾收集器的實現,對于管理短期對象(比如 UI 小部件),Dart 更加高效。Dart 可以通過 Future 和 Stream 的特性和 API 實現異步編程。

三丶Dart 語言特性

  1. 單進程異步事件模型
  2. 強類型,可以類型推斷
  3. DartVM,具有極高的運行效率和優秀的代碼運行優化,根據早前的基準測試,性能比肩 Java7 的 JVM
  4. 獨特的隔離區(lsolate),可以實現多線程
  5. 面向對象編程,一切數據類型均派生自Object
  6. 運算符重載,泛型支持
  7. 強大的 Future 和 Stream 模型,可以簡單實現高效的代碼
  8. Minix 特性,可以更好的實現方法復用
  9. 全平臺語言,可以很好地勝任移動和前后端的開發
  10. 在語法上,Dart 提供了很多便捷的操作,可以明顯減少代碼量。比如字符連接,可以直接“my name is $name,age is
    $age”,無需+號拼接,也無需做類型轉換

四丶應用場景

  • dart語言。服務端開發
    1、命令行應用
    2、HTTP 服務端

  • Web 開發
    在這里插入圖片描述

  • Android 和 iOS 開發
    在這里插入圖片描述

五丶版本

  • Dart1.x 為穩定版本
  • Dart2.x 目前為開發版本
  • 課程以 Dart2 最新版本進行講解

dart多線程,六丶Dart 內置庫

包名描述
dart:async異步編程,提供Future,Stream 類
dart:collection集合
dart:convert不同類型的字符編碼解碼
dart:coreDart 語言核心功能,內置類型
dart:html網頁開發用到的庫
dart:io文件讀寫,IO相關
dart:math數字常量及函數,隨機算法等
dart:svg事件和動畫矢量圖支持

七丶輸出“Hello World”

main(){print('你好dart');
}

八丶學習資料

Dart 官方文檔

2、Dart 安裝

一丶 下載Dart(含SDK)

https://gekorm.com/dart-windows/

二丶 設置環境變量
【1】
Name:DART_SDK
Key:D:\program\Dart\Dart\dart-sdk
在這里插入圖片描述
【2】
Name:Path
Key:D:\program\Dart\Dart\dart-sdk;

在這里插入圖片描述

三丶 檢測是是否成功
【1】dart --version
在這里插入圖片描述

四丶 安裝VSCode
【1】
可以參考我的博文:如何下載Visual Studio Code及配置教程
【2】
點開左邊工具欄,第四個,搜索dart,下載這個插件
在這里插入圖片描述
下載Code Runner插件
在這里插入圖片描述
【3】寫代碼,運行

在這里插入圖片描述

3、知識點

3.1、Dart介紹、Dart環境搭建、Dart開發工具

一丶 Dart介紹
Dart是由谷歌開發的計算機編程語言,它可以被用于web、服務器、移動應用 和物聯網等領域的開發。
Dart誕生于2011年,號稱要取代JavaScript。但是過去的幾年中一直不溫不火。直到Flutter的出現現在被人們重新重視。
要學Flutter的話我們必須首先得會Dart。
官網:https://dart.dev/

二丶Dart環境搭建

1丶 下載Dart(含SDK)

https://gekorm.com/dart-windows/

2丶 設置環境變量
【1】
Name:DART_SDK
Key:D:\program\Dart\Dart\dart-sdk
在這里插入圖片描述
【2】
Name:Path
Key:D:\program\Dart\Dart\dart-sdk;

在這里插入圖片描述

3丶 檢測是是否成功
【1】dart --version
在這里插入圖片描述

4丶 安裝VSCode
【1】
可以參考我的博文:如何下載Visual Studio Code及配置教程
【2】
點開左邊工具欄,第四個,搜索dart,下載這個插件
在這里插入圖片描述
下載Code Runner插件
在這里插入圖片描述
【3】寫代碼,運行

在這里插入圖片描述

三丶 Dart開發工具
Dart的開發工具有很多: IntelliJ IDEA 、 WebStorm、 Atom、Vscode等

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

1、找到vscode插件安裝dart

2、找到vscode插件安裝code runner Code Runner 可以運行我們的文件

3.2、變量、常量、命名規則、入口方法的兩種定義方式

一丶 入口方法的兩種定義方式
方式一:

main(){print('你好dart');
}

方式二:

void main(){print('你好dart');
}

二丶 變量
1、變量的概念

dart是一個強大的腳本類語言,可以不預先定義變量類型 ,自動會類型推倒

dart中定義變量可以通過var關鍵字可以通過類型來申明變量

如:

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

注意: var 后就不要寫類型 , 寫了類型 不要var 兩者都寫 var a int = 5; 報錯

2、定義變量

void main(){var str='你好dart';var myNum=1234;print(str);print(myNum);//字符串String str='你好dart';print(str);//數字類型int myNum=12354;print(myNum);//dart里面有類型校驗var str='';str=1234;print(str);String str="2131242";print(str);int myNum=1243214;print(myNum);

三丶 常量

1、常量的概念

final 和 const修飾符

const值不變 一開始就得賦值
final 可以開始不賦值 只能賦一次 ; 而final不僅有const的編譯時常量的特性,最重要的它是運行時常量,并且final是惰性初始化,即在運行時第一次使用前才初始化

永遠不改量的量,請使用final或const修飾它,而不是使用var或其他變量類型。

2、定義常量

void main(){var str='this is a str';str='你好 str';print(str);int myNum=1234;myNum=4567;print(myNum);//const常量const PI=3.14159;PI=123.1243; //錯誤的寫法 常量不可以修改print(PI);// final 常量final PI=3.14159;PI=124214.214124;   //錯誤寫法print(PI);final a=new DateTime.now();print(a);   //2019-05-10 15:59:02.966122//const a=new DateTime.now();   //報錯了//區別:final 可以開始不賦值 只能賦一次 ; 而final不僅有const的編譯時常量的特性,最重要的它是運行時常量,并且final是惰性初始化,即在運行時第一次使用前才初始化}

四丶 命名規則
1、變量名稱必須由數字、字母、下劃線和美元符($)組成。

2、注意:標識符開頭不能是數字

3、標識符不能是保留字和關鍵字。

4、變量的名字是區分大小寫的如: age和Age是不同的變量。在實際的運用中,也建議,不要用一個單詞大小寫區分兩個變量。

5、標識符(變量名稱)一定要見名思意 :變量名稱建議用名詞,方法名稱建議用動詞

3.3、常用數據類型、字符串類型、數值類型、布爾類型、List集合類型、Maps類型

一丶 數據類型

常用數據類型:
Numbers(數值):
int
double
Strings(字符串)
String
Booleans(布爾)
bool
List(數組)
在Dart中,數組是列表對象,所以大多數人只是稱它們為列表
Maps(字典)
通常來說,Map 是一個鍵值對相關的對象。 鍵和值可以是任何類型的對象。每個 鍵 只出現一次, 而一個值則可以出現多次

項目中用不到的數據類型 (用不到):
Runes
Rune是UTF-32編碼的字符串。它可以通過文字轉換成符號表情或者代表特定的文字。

  main() {var clapping = '\u{1f44f}';print(clapping);print(clapping.codeUnits);print(clapping.runes.toList());Runes input = new Runes('\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');print(new String.fromCharCodes(input));}

Symbols
Symbol對象表示在Dart程序中聲明的運算符或標識符。您可能永遠不需要使用符號,但它們對于按名稱引用標識符的API非常有用,因為縮小會更改標識符名稱而不會更改標識符符號。要獲取標識符的符號,請使用符號文字,它只是#后跟標識符:

在 Dart 中符號用 # 開頭來表示,入門階段不需要了解這東西,可能永遠也用不上。
http://dart.goodev.org/guides/libraries/library-tour#dartmirrors—reflection

二丶 字符串類型
Dart數據類型:字符串類型

void main(){//1、字符串定義的幾種方式var str1='this is str1';var str2="this is str2";print(str1);print(str2);String str1='this is str1';String str2="this is str2";print(str1);print(str2);String str1='''this is str1this is str1this is str1''';print(str1);String str1="""this is str1this is str1this is str1""";print(str1);//2、字符串的拼接String str1='你好';String str2='Dart';print("$str1 $str2");print(str1 + str2);print(str1 +" "+ str2);

三丶 數值類型
Dart數據類型:數值類型
int
double

void main(){//1、int   必須是整型int a=123;a=45;print(a);//2、double  既可以是整型 也可是浮點型double b=23.5;b=24;print(b);//3、運算符// + - * / %var c=a+b;print(c);
}

四丶 布爾類型
Dart數據類型:布爾類型

bool 值true/false

void main(){//1、boolbool flag1=true;print(flag1);bool flag2=false;print(flag2);//2、條件判斷語句var flag=true;if(flag){print('真');}else{print('假');}var a=123;var b='123';if(a==b){print('a=b');}else{print('a!=b');}var a=123;var b=123;if(a==b){print('a=b');}else{print('a!=b');}
}

五丶 List集合類型
Dart數據類型: List(數組/集合)

void main(){//1、第一種定義List的方式var l1=['aaa','bbbb','cccc'];print(l1);print(l1.length);print(l1[1]);//2、第二種定義List的方式var l2=new List();l2.add('張三');l2.add('李四');l2.add('王五');print(l2);print(l2[2]);//3、定義List指定類型var l3=new List<String>();l3.add('張三');l3.add(123);print(l3);
}

六丶 Maps類型
Dart數據類型: Maps(字典)

void main(){//第一種定義 Maps的方式var person={"name":"張三","age":20,"work":["程序員","送外賣"]};print(person);print(person["name"]);print(person["age"]);print(person["work"]);//第二種定義 Maps的方式var p=new Map();p["name"]="李四";p["age"]=22;p["work"]=["程序員","送外賣"];print(p);print(p["age"]);  
}

七丶 類型判斷
Dart判斷數據類型 :
是通過is 關鍵詞來判斷類型

void main(){var str='1234';if(str is String){print('是string類型');}else if(str is int){print('int');}else{print('其他類型');}var str=123;if(str is String){print('是string類型');}else if(str is int){print('int');}else{print('其他類型');}
}

3.4、運算符、條件判斷、類型轉換

一丶 運算符

算術運算符

+    -    *    /     ~/ (取整)     %(取余)

關系運算符

== != > < >= <=

邏輯運算符

! && ||

賦值運算符

基礎賦值運算符 = ??=

復合賦值運算符 += -= *= /= %= ~/=

條件表達式
if else switch case
三目運算符
??運算符:

二丶 算術運算符

void main(){int a=13;int b=5;print(a+b);   //加print(a-b);   //減print(a*b);   //乘print(a/b);   //除print(a%b);   //其余print(a~/b);  //取整var c=a*b;print('--------');print(c);

三丶 關系運算符

void main(){//  ==    !=   >    <    >=    <=int a=5;int b=3;print(a==b);   //判斷是否相等print(a!=b);   //判斷是否不等print(a>b);   //判斷是否大于print(a<b);   //判斷是否小于print(a>=b);   //判斷是否大于等于print(a<=b);   //判斷是否小于等于if(a>b){print('a大于b');}else{print('a小于b');}
}

四丶 邏輯運算符

void main(){/* ! 取反 */ bool flag=false;print(!flag);   //取反/* &&并且:全部為true的話值為true 否則值為false */ bool a=true;bool b=true;print(a && b);/* ||或者:全為false的話值為false 否則值為true */ bool a=false;bool b=false;print(a || b);//如果一個人的年齡是20 并且 sex是女的話我們打印這個人int age=20;String sex="女";if(age==20 && sex=="女"){print("$age --- $sex");}else{print("不打印");}//如果一個人的年齡是20 或者 sex是女的話我們打印這個人int age=23;String sex="女";if(age==20 || sex=="女"){print("$age --- $sex");}else{print("不打印");}
}

五丶 基礎賦值運算符&復合賦值運算符

void main(){//  1、基礎賦值運算符   =   ??=      int a=10;int b=3;print(a);int c=a+b;   //從右向左b??=23;  表示如果b為空的話把 23賦值給bint b=6;b??=23;print(b);int b;b??=23;print(b);//2、  復合賦值運算符   +=  -=  *=   /=   %=  ~/=var a=12;a=a+10;print(a);var a=13;a+=10;   //表示a=a+10print(a);var a=4;a*=3;  //a=a*3;print(a);
}

六丶 條件表達式

void main(){//1、if  else   switch case bool flag=true;if(flag){print('true');}else{print('false');}//判斷一個人的成績 如果大于60 顯示及格   如果大于 70顯示良好  如果大于90顯示優秀var score=41;if(score>90){print('優秀');}else if(score>70){print('良好');}else if(score>=60){print('及格');}else{print('不及格');}var sex="女";switch(sex){case "男":print('性別是男');break;case "女":print('性別是女');print('性別是女');break;default:print('傳入參數錯誤');break;}//2、三目運算符 var falg=true;var c;if(falg){c='我是true';}else{c="我是false";}print(c);bool flag=false;String c=flag?'我是true':'我是false';print(c);//3  ??運算符var a;var b= a ?? 10;print(b);   10var a=22;var b= a ?? 10;print(b);
}

3.5、自增自減運算符、for、while、do…while循環、continue、break、多維列表循環

一丶 自增自減運算符

void main(){//   ++  --   表示自增 自減 1//   在賦值運算里面 如果++ -- 寫在前面 這時候先運算 再賦值,如果++ --寫在后面 先賦值后運行運算var a=10;var b=a--;print(a);  //9print(b);  //10var a=10;a++;   //a=a+1;print(a);var a=10;a--;    //a=a-1;print(a);var a=10;var b=a++;print(a);  //11print(b);  //10var a=10;var b=++a;print(a);  //11print(b);  //11var a=10;var b=--a;print(a);  //9print(b);  //9var a=10;var b=a--;print(a);  //9print(b);  //10var a=10;++a;print(a);
}

二丶 for循環

// for基本語法for (int i = 1; i<=100; i++) {   print(i);}//第一步,聲明變量int i = 1;//第二步,判斷i <=100//第三步,print(i);//第四步,i++//第五步 從第二步再來,直到判斷為falsevoid main(){for(int i=1;i<=10;i++){print(i);}//1、打印0-50所有的偶數for(int i=0;i<=50;i++){if(i%2==0){print(i);}}//2、求 1+2+3+4 +...100的和var sum=0;for(var i=1;i<=100;i++){sum+=i;}print(sum);sum=0+1;sum=0+1+2;sum=0+1+2+3+...+100;// 3、計算5的階乘   (1*2*3*4*5    n的階乘1*2……*n)var sum=1;for(var i=1;i<=5;i++){sum*=i;}print(sum);sum=1*1;sum=1*1*2;sum=1*1*3;sum=1*1*3*4*5;//4、打印List  ['張三','李四','王五'] 里面的內容List list=['張三','李四','王五'];print(list[1]);for(var i=0;i<list.length;i++){print(list[i]);}//5、打印List List list=[{"title":"新聞111"},{"title":"新聞222"},{"title":"新聞333"}];print(list[1]);for(var i=0;i<list.length;i++){print(list[i]['title']);}//4、定義一個二維數組 打印里面的內容List list=[{"cate":'國內',"news":[{"title":"國內新聞1"},{"title":"國內新聞2"},{"title":"國內新聞3"}]},{"cate":'國際',"news":[{"title":"國際新聞1"},{"title":"國際新聞2"},{"title":"國際新聞3"}]}];/*國內國內新聞1國內新聞2國內新聞3國際國際新聞1國際新聞2*/for(var i=0;i<list.length;i++){print(list[i]["cate"]);print('-------------');for(var j=0;j<list[i]["news"].length;j++){print(list[i]["news"][j]["title"]);}}
}

三丶 while、do…while循環

	語法格式:	while(表達式/循環條件){				}			do{語句/循環體		}while(表達式/循環條件);注意: 1、最后的分號不要忘記2、循環條件中使用的變量需要經過初始化3、循環體中,應有結束循環的條件,否則會造成死循環。void main(){int i=1;while(i<=10){print(i);}//死循環int i=1;while(i<=10){print(i);i++;}//1、求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);whiledo while的區別   第一次循環條件不成立的情況下int i=10;while(i<2){print('執行代碼');}var j=10;	  do{print('執行代碼');}while(j<2);
}

四丶 break和continue

			break語句功能:1、在switch語句中使流程跳出switch結構。2、在循環語句中使流程跳出當前循環,遇到break 循環終止,后面代碼也不會執行強調:1、如果在循環中已經執行了break語句,就不會執行循環體中位于break后的語句。2、在多層循環中,一個break語句只能向外跳出一層break可以用在switch case中 也可以用在 for 循環和 while循環中continue語句的功能:【注】只能在循環語句中使用,使本次循環結束,即跳過循環體重下面尚未執行的語句,接著進行下次的是否執行循環的判斷。continue可以用在for循環以及 while循環中,但是不建議用在while循環中,不小心容易死循環
main() {for(var i=1;i<=10;i++){print(i);}//1、如果i等于4的話跳過for(var i=1;i<=10;i++){if(i==4){continue;  /*跳過當前循環體 然后循環還會繼續執行*/}print(i);}//2、如果 i等于4的話跳出循環for(var i=1;i<=10;i++){if(i==4){break;  /*跳出循環體*/}print(i);}//3、break語句只能向外跳出一層for(var i=0;i<5;i++){	 	    	print('外層---$i');for(var j=0;j<3;j++){	if(j==1){break;}print('里層$j');		 	}	}//4、while循環 break跳出循環var i=1;while(i<=10){if(i==4){break;}print(i);i++;}var sex="男";switch (sex) {case "男":print('男');break;case "女":print('男');break;default:}
}

3.6、集合類型List Set Map詳解 以及循環語句 forEach map where any every

一丶 list集合
常用屬性:
length 長度
reversed 翻轉
isEmpty 是否為空
isNotEmpty 是否不為空
常用方法:
add 增加
addAll 拼接數組
indexOf 查找 傳入具體值
remove 刪除 傳入具體值
removeAt 刪除 傳入索引值
fillRange 修改
insert(index,value); 指定位置插入
insertAll(index,list) 指定位置插入List
toList() 其他類型轉換成List
join() List轉換成字符串
split() 字符串轉化成List
forEach
map
where
any
every

void main(){List myList=['香蕉','蘋果','西瓜'];print(myList[1]);var list=new List();list.add('111');list.add('222');print(list);//List里面的屬性:List myList=['香蕉','蘋果','西瓜'];print(myList.length);print(myList.isEmpty);print(myList.isNotEmpty);print(myList.reversed);  //對列表倒序排序var newMyList=myList.reversed.toList();print(newMyList);//List里面的方法:List myList=['香蕉','蘋果','西瓜'];myList.add('桃子');   //增加數據  增加一個myList.addAll(['桃子','葡萄']);  //拼接數組print(myList);print(myList.indexOf('蘋x果'));    //indexOf查找數據 查找不到返回-1  查找到返回索引值myList.remove('西瓜');myList.removeAt(1);print(myList);List myList=['香蕉','蘋果','西瓜'];myList.fillRange(1, 2,'aaa');  //修改myList.fillRange(1, 3,'aaa');  myList.insert(1,'aaa');      //插入  一個myList.insertAll(1, ['aaa','bbb']);  //插入 多個print(myList);// List myList=['香蕉','蘋果','西瓜'];// var str=myList.join('-');   //list轉換成字符串// print(str);// print(str is String);  //truevar str='香蕉-蘋果-西瓜';var list=str.split('-');print(list);print(list is List);}

3.7、函數的定義 可選參數 默認參數 命名參數

一丶 方法的定義 變量 方法的作用域

內置方法/函數:
print();
自定義方法:
自定義方法的基本格式:
返回類型 方法名稱(參數1,參數2,…){
方法體
return 返回值;
}

void printInfo(){print('我是一個自定義方法');
}int getNum(){var myNum=123;return myNum;
}String printUserInfo(){return 'this is str';
}List getList(){return ['111','2222','333'];
}void main(){print('調用系統內置的方法');printInfo();var n=getNum();print(n);print(printUserInfo());print(getList());print(getList());//演示方法的作用域void xxx(){aaa(){print(getList());print('aaa');}aaa();}// aaa();  錯誤寫法 xxx();  //調用方法
}

二丶 方法傳參 、默認參數、可選參數、命名參數 、方法作為參數

//調用方法傳參main() {//1、定義一個方法 求1到這個數的所有數的和      60    1+2+3+。。。+60int 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);//2、定義一個方法然后打印用戶信息String printUserInfo(String username,int age){  //行參return "姓名:$username---年齡:$age";}print(printUserInfo('張三',20)); //實參//3、定義一個帶可選參數的方法String printUserInfo(String username,[int age]){  //行參if(age!=null){return "姓名:$username---年齡:$age";}return "姓名:$username---年齡保密";}print(printUserInfo('張三',21)); //實參print(printUserInfo('張三'));//4、定義一個帶默認參數的方法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));//5、定義一個命名參數的方法String printUserInfo(String username,{int age,String sex='男'}){  //行參if(age!=null){return "姓名:$username---性別:$sex--年齡:$age";}return "姓名:$username---性別:$sex--年齡保密";}print(printUserInfo('張三',age:20,sex:'未知'));//6、實現一個 把方法當做參數的方法var fn=(){print('我是一個匿名方法');};      fn();//方法fn1(){print('fn1');}//方法fn2(fn){fn();}//調用fn2這個方法 把fn1這個方法當做參數傳入fn2(fn1);}

3.8、函數、箭頭函數 匿名函數 閉包等

一丶 箭頭函數 函數的相互調用

void main(){/*需求:使用forEach打印下面List里面的數據*/List list=['蘋果','香蕉','西瓜'];list.forEach((value){print(value);});list.forEach((value)=>print(value));list.forEach((value)=>{print(value)});/*需求:修改下面List里面的數據,讓數組中大于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());/*
需求:    1、定義一個方法isEvenNumber來判斷一個數是否是偶數  2、定義一個方法打印1-n以內的所有偶數
*///定義一個方法isEvenNumber來判斷一個數是否是偶數  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);
}

3.9、對象、類

一丶 面向對象的介紹 以及Data內置對象

面向對象編程(OOP)的三個基本特征是:封裝、繼承、多態

封裝:封裝是對象和類概念的主要特性。封裝,把客觀事物封裝成抽象的類,并且把自己的部分屬性和方法提供給其他對象調用, 而一部分屬性和方法則隱藏。

繼承:面向對象編程 (OOP) 語言的一個主要功能就是“繼承”。繼承是指這樣一種能力:它可以使用現有類的功能,并在無需重新編寫原來的類的情況下對這些功能進行擴展。

多態:允許將子類類型的指針賦值給父類類型的指針, 同一個函數調用會有不同的執行效果 。

Dart所有的東西都是對象,所有的對象都繼承自Object類。

Dart是一門使用類和單繼承的面向對象語言,所有的對象都是類的實例,并且所有的類都是Object的子類

一個類通常由屬性和方法組成。

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

二丶 創建類使用類

Dart是一門使用類和單繼承的面向對象語言,所有的對象都是類的實例,并且所有的類都是Object的子類

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(){//實例化var p1=new Person();print(p1.name);p1.getInfo();Person p1=new Person();print(p1.name);p1.setInfo(28);p1.getInfo();}

三丶 自定義類的默認構造函數

class Person{String name='張三';int age=20; //默認構造函數Person(){print('這是構造函數里面的內容  這個方法在實例化的時候觸發');}void printInfo(){   print("${this.name}----${this.age}");}
}//張三  李四  王五class Person{String name;int age; //默認構造函數Person(String name,int age){this.name=name;this.age=age;}void printInfo(){   print("${this.name}----${this.age}");}
}class Person{String name;int age; //默認構造函數的簡寫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();}

四丶 自定義類的命名構造函數
dart里面構造函數可以寫多個

class Person{String name;int age; //默認構造函數的簡寫Person(this.name,this.age);Person.now(){print('我是命名構造函數');}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();   //實例化DateTime調用它的命名構造函數print(d);Person p1=new Person('張三', 20);   //默認實例化類的時候調用的是 默認構造函數Person p1=new Person.now();   //命名構造函數Person p1=new Person.setInfo('李四',30);p1.printInfo(); 
}

五丶 把類單獨抽離成一個模塊
Person.dart

class Person{String name;int age; //默認構造函數的簡寫Person(this.name,this.age);Person.now(){print('我是命名構造函數');}Person.setInfo(String name,int age){this.name=name;this.age=age;}void printInfo(){   print("${this.name}----${this.age}");}
}

main.dart

import 'lib/Person.dart';void main(){Person p1=new Person.setInfo('李四1',30);p1.printInfo(); 
}

六丶 私有方法 和私有屬性

Animal.dart

class Animal{String _name;   //私有屬性int age; //默認構造函數的簡寫Animal(this._name,this.age);void printInfo(){   print("${this._name}----${this.age}");}String getName(){ return this._name;} void _run(){print('這是一個私有方法');}execRun(){this._run();  //類里面方法的相互調用}
}

main.dart

/*
Dart和其他面向對象語言不一樣,Data中沒有 public  private protected這些訪問修飾符合但是我們可以使用_把一個屬性或者方法定義成私有。*/import 'lib/Animal.dart';void main(){Animal a=new Animal('小狗', 3);print(a.getName());a.execRun();   //間接的調用私有方法
}

七丶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}");      //注意調用直接通過訪問屬性的方式訪問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);}

八丶 類中的初始化列表

// Dart中我們也可以在構造函數體運行之前初始化實例變量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()); }

3.10、類 靜態成員 操作符 類的繼承

一丶 靜態成員 靜態方法

Dart中的靜態成員:

1、使用static 關鍵字來實現類級別的變量和函數

2、靜態方法不能訪問非靜態成員,非靜態方法可以訪問靜態成員

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(){  /*非靜態方法可以訪問靜態成員以及非靜態成員*/print(name);  //訪問靜態屬性print(this.age);  //訪問非靜態屬性show();   //調用靜態方法}static void printUserInfo(){//靜態方法print(name);   //靜態屬性show();        //靜態方法print(this.age);     //靜態方法沒法訪問非靜態的屬性this.printInfo();   //靜態方法沒法訪問非靜態的方法printInfo();}
}main(){print(Person.name);Person.show(); Person p=new Person();p.printInfo(); Person.printUserInfo();
}

二丶 對象操作符

Dart中的對象操作符:

? 條件運算符 (了解)
as 類型轉換
is 類型判斷
… 級聯操作 (連綴) (記住)

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

三丶 類的繼承-簡單繼承

面向對象的三大特性:封裝 、繼承、多態

Dart中的類的繼承:
1、子類使用extends關鍵詞來繼承父類
2、子類會繼承父類里面可見的屬性和方法 但是不會繼承構造函數
3、子類能復寫父類的方法 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關鍵詞的使用 實例化自類給父類構造函數傳參

面向對象的三大特性:封裝 、繼承、多態

Dart中的類的繼承:
1、子類使用extends關鍵詞來繼承父類
2、子類會繼承父類里面可見的屬性和方法 但是不會繼承構造函數
3、子類能復寫父類的方法 getter和setter

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

五丶 super關鍵詞的使用 實例化自類給父類構造函數傳參

class Person {String name;num age; Person(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(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();
}

六丶 實例化自類給命名構造函數傳參

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

七丶 覆寫父類的方法

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');}//覆寫父類的方法@override       //可以寫也可以不寫  建議在覆寫父類方法的時候加上 @override void printInfo(){print("姓名:${this.name}---年齡:${this.age}"); }@overridework(){print("${this.name}的工作是寫代碼");}
}main(){ Web w=new Web('李四',20);w.printInfo();w.work();
}

八丶 自類里面調用父類的方法

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();  //自類調用父類的方法}//覆寫父類的方法@override       //可以寫也可以不寫  建議在覆寫父類方法的時候加上 @override void printInfo(){print("姓名:${this.name}---年齡:${this.age}"); }
}main(){ Web w=new Web('李四',20);// w.printInfo();w.run();
}

3.11、抽象類 多態 以及接口

一丶 抽象類

Dart中抽象類: Dart抽象類主要用于定義標準,子類可以繼承抽象類,也可以實現抽象類接口。

1、抽象類通過abstract 關鍵字來定義

2、Dart中的抽象方法不能用abstract聲明,Dart中沒有方法體的方法我們稱為抽象方法。

3、如果子類繼承抽象類必須得實現里面的抽象方法

4、如果把抽象類當做接口實現的話必須得實現抽象類里面定義的所有屬性和方法。

5、抽象類不能被實例化,只有繼承它的子類可以

extends抽象類 和 implements的區別:

1、如果要復用抽象類里面的方法,并且要用抽象方法約束自類的話我們就用extends繼承抽象類

2、如果只是把抽象類當做標準的話我們就用implements實現抽象類

案例:定義一個Animal 類要求它的子類必須包含eat方法

abstract class Animal{eat();   //抽象方法run();  //抽象方法  printInfo(){print('我是一個抽象類里面的普通方法');}
}class Dog extends Animal{@overrideeat() {print('小狗在吃骨頭');}@overriderun() {// TODO: implement runprint('小狗在跑');}  
}
class Cat extends Animal{@overrideeat() {// TODO: implement eatprint('小貓在吃老鼠');}@overriderun() {// TODO: implement runprint('小貓在跑');}
}main(){Dog d=new Dog();d.eat();d.printInfo();Cat c=new Cat();c.eat();c.printInfo();// Animal a=new Animal();   //抽象類沒法直接被實例化
}

3.12、一個類實現多個接口 以及Dart中的Mixins

一丶 implements實現多個接口

abstract class A{String name;printA();
}abstract class B{printB();
}class C implements A,B{  @overrideString name;  @overrideprintA() {print('printA');}@overrideprintB() {// TODO: implement printBreturn null;}
}void main(){C c=new C();c.printA();}

二丶 mixins

mixins的中文意思是混入,就是在類中混入其他功能。

在Dart中可以使用mixins實現類似多繼承的功能

因為mixins使用的條件,隨著Dart版本一直在變,這里講的是Dart2.x中使用mixins的條件:

1、作為mixins的類只能繼承自Object,不能繼承其他類
2、作為mixins的類不能有構造函數
3、一個類可以mixins多個mixins類
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);}

三丶 mixins 的類型

mixins的實例類型是什么?

很簡單,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();  print(c is C);    //trueprint(c is A);    //trueprint(c is B);   //true// var a=new A();// print(a is Object);}

3.13、泛型、泛型方法 、泛型類、泛型接口

一丶 泛型方法

通俗理解:泛型就是解決 類 接口 方法的復用性、以及對不特定數據類型的支持(類型校驗)

只能返回string類型的數據String getData(String value){return value;}同時支持返回 string類型 和int類型  (代碼冗余)String getData1(String value){return value;}int getData2(int value){return value;}同時返回 string類型 和number類型       不指定類型可以解決這個問題getData(value){return value;}//不指定類型放棄了類型檢查。我們現在想實現的是傳入什么 返回什么。比如:傳入number 類型必須返回number類型  傳入 string類型必須返回string類型T getData<T>(T value){return value;}getData<T>(T value){return value;}void main(){print(getData(21));print(getData('xxx'));getData<String>('你好');print(getData<int>(12));}

二丶 泛型類

集合List 泛型類的用法

案例:把下面類轉換成泛型類,要求List里面可以增加int類型的數據,也可以增加String類型的數據。但是每次調用增加的類型要統一

class PrintClass{List list=new List<int>();void add(int value){this.list.add(value);}void printInfo(){          for(var i=0;i<this.list.length;i++){print(this.list[i]);}}}PrintClass p=new PrintClass();p.add(1);p.add(12);p.add(5);p.printInfo();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();p.add(11);p.add('xxx');p.add(5);p.printInfo();PrintClass p=new PrintClass<String>();p.add('你好');p.add('哈哈');p.printInfo();PrintClass p=new PrintClass<int>();p.add(12);p.add(23);p.printInfo();List list=new List();list.add(12);list.add("你好");print(list);List list=new List<String>();// list.add(12);  //錯誤的寫法list.add('你好');list.add('你好1');print(list);List list=new List<int>();// list.add("你好");  //錯誤寫法list.add(12); print(list);
}

三丶 泛型接口

實現數據緩存的功能:有文件緩存、和內存緩存。內存緩存和文件緩存按照接口約束實現。

1、定義一個泛型接口 約束實現它的子類必須有getByKey(key) 和 setByKey(key,value)

2、要求setByKey的時候的value的類型和實例化子類的時候指定的類型一致

  abstract class ObjectCache {getByKey(String key);void setByKey(String key, Object value);}abstract class StringCache {getByKey(String key);void setByKey(String key, String value);}abstract class Cache<T> {getByKey(String key);void setByKey(String key, T value);}abstract class Cache<T>{getByKey(String key);void setByKey(String key, T value);
}class FlieCache<T> implements Cache<T>{@overridegetByKey(String key) {    return null;}@overridevoid setByKey(String key, T value) {print("我是文件緩存 把key=${key}  value=${value}的數據寫入到了文件中");}
}class MemoryCache<T> implements Cache<T>{@overridegetByKey(String key) {   return null;}@overridevoid setByKey(String key, T value) {print("我是內存緩存 把key=${key}  value=${value} -寫入到了內存中");}
}
void main(){MemoryCache m=new MemoryCache<String>();m.setByKey('index', '首頁數據');MemoryCache m=new MemoryCache<Map>();m.setByKey('index', {"name":"張三","age":20});
}

3.14、庫 自定義庫、系統庫、第三方庫

一丶 庫

前面介紹Dart基礎知識的時候基本上都是在一個文件里面編寫Dart代碼的,但實際開發中不可能這么寫,模塊化很重要,所以這就需要使用到庫的概念。

在Dart中,庫的使用時通過import關鍵字引入的。

library指令可以創建一個庫,每個Dart文件都是一個庫,即使沒有使用library指令來指定。

Dart中的庫主要有三種:

1、我們自定義的庫
import ‘lib/xxx.dart’;
2、系統內置庫
import ‘dart:math’;
import ‘dart:io’;
import ‘dart:convert’;
3、Pub包管理系統中的庫
https://pub.dev/packages
https://pub.flutter-io.cn/packages
https://pub.dartlang.org/flutter/
1、需要在自己想項目根目錄新建一個pubspec.yaml
2、在pubspec.yaml文件 然后配置名稱 、描述、依賴等信息
3、然后運行 pub get 獲取包下載到本地
4、項目中引入庫 import ‘package:http/http.dart’ as http; 看文檔使用

二丶 導入自己本地庫

Animal.dart

class Animal{String _name;   //私有屬性int age; //默認構造函數的簡寫Animal(this._name,this.age);void printInfo(){   print("${this._name}----${this.age}");}String getName(){ return this._name;} void _run(){print('這是一個私有方法');}execRun(){this._run();  //類里面方法的相互調用}
}
import 'lib/Animal.dart';
main(){var a=new Animal('小黑狗', 20);print(a.getName());
}

三丶 導入系統內置庫 math庫

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

四丶 導入系統內置庫實現請求數據httpClient

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

五丶 關于 Async Await

async和await
這兩個關鍵字的使用只需要記住兩點:
只有async方法才能使用await關鍵字調用方法
如果調用別的async方法必須使用await關鍵字

async是讓方法變成異步。
await是等待異步方法執行完成。

void main() async{var result = await testAsync();print(result);
}
//異步方法
testAsync() async{return 'Hello async';
}

六丶 導入Pub包管理系統中的庫

pub包管理系統:

1、從下面網址找到要用的庫
https://pub.dev/packages
https://pub.flutter-io.cn/packages
https://pub.dartlang.org/flutter/

2、創建一個pubspec.yaml文件,內容如下

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

3、配置dependencies

4、運行pub get 獲取遠程庫

5、看文檔引入庫使用

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

七丶 庫的重命名 Dart沖突解決

Person1.dart

class Person{String name;int age; //默認構造函數的簡寫Person(this.name,this.age);  Person.setInfo(String name,int age){this.name=name;this.age=age;}void printInfo(){   print("Person1:${this.name}----${this.age}");}
}

Person2.dart

class Person{String name;int age; //默認構造函數的簡寫Person(this.name,this.age);  Person.setInfo(String name,int age){this.name=name;this.age=age;}void printInfo(){   print("Person2:${this.name}----${this.age}");}
}
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();
}

八丶 部分導入

myMath.dart

void getName(){print('張三');
}
void getAge(){print(20);
}
void getSex(){print('男');
}

部分導入
如果只需要導入庫的一部分,有兩種模式:

模式一:只導入需要的部分,使用show關鍵字,如下例子所示:
import ‘package:lib1/lib1.dart’ show foo;

模式二:隱藏不需要的部分,使用hide關鍵字,如下例子所示:
import ‘package:lib2/lib2.dart’ hide foo;

import 'lib/myMath.dart' hide getName;void main(){
//  getName();getAge();
}

九丶 延遲加載

也稱為懶加載,可以在需要的時候再進行加載。
懶加載的最大好處是可以減少APP的啟動時間。懶加載使用deferred as關鍵字來指定,如下例子所示:import 'package:deferred/hello.dart' deferred as hello;當需要使用的時候,需要使用loadLibrary()方法來加載:greet() async {await hello.loadLibrary();hello.printGreeting();
}

4、常見問題

4.1、String和int互轉

int.parse("100");
123.toString();

4.2、字符串(String)的相關方法

更多請參考原文

字符串定義
使用單引號或雙引號

String a = “abcdefg”;
String b = ‘12345’;
創建多行字符串,保留內在格式
使用三個單引號或三個雙引號 創建多行字符串,保留內在格式,如換行和縮進等,里面寫什么輸出就是什么。
三個單引號
String e = ‘’'asd
fdsd
fff

''';

三個雙引號 
String f = “”" 1
2
3
4
“”";

4.3、JSON

1.手動序列化JSON
Flutter中基本的JSON序列化非常簡單,Flutter有一個內置的dart:convert庫,其中包含一個簡單的JSON解碼器和編碼器。下面簡單實現一下:
詳情請參考原文

4.4、

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/194740.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息