Dart學(xué)習(xí)
=>只有一行代碼可以使用剪頭函數(shù) => print(‘a(chǎn)’) 或者{ print(‘a(chǎn)’)} 內(nèi)部語(yǔ)句后面不需要加分號(hào)其他的每個(gè)語(yǔ)句后面必須要加分號(hào)素征;
定義變量:
Dart里面是有類型校驗(yàn)的
一個(gè)變量沒有被初始化,他的默認(rèn)值就是null思币,比如 var a; 此時(shí)a就是null
var 可以定義任意類型赴邻,但是如果定義好了,就不能賦值為別的類型
比如var a =‘’;a = 123;會(huì)報(bào)錯(cuò)
String:?jiǎn)我?hào)指蚜,雙引號(hào)骂租,三引號(hào)(可以寫多行)
字符串拼接:print(“$str1$str2”)或者print(str1 + str2)?
數(shù)值類型
int:必須是整型
double:既可以是整型,也可以是浮點(diǎn)型
運(yùn)算符
基本算數(shù)運(yùn)算符:+ - * / %(取余)? ~/(取整)
關(guān)系運(yùn)算符:== != > < >= <=返回值是true或者false
邏輯運(yùn)算符:镣陕!(取反) && ||
賦值運(yùn)算符:= ??= += -= *= /= %=~/=
??=:int a = 10;a??=23;(首先判斷a是否為null谴餐,如果是null,則23賦值給a呆抑,如果不為空岂嗓,不變)
條件表達(dá)式:if else、switch case理肺、三目運(yùn)算符摄闸、??運(yùn)算符
switch case:判斷固定值的時(shí)候比if else效率高
三目運(yùn)算:c =? flag==true?”我是true”:”我是false”
??:var a = 10;var b = a ?? 23;(判斷a是否為null善镰,如果是的話b為23妹萨,否則b為a的值)
類型轉(zhuǎn)換
Number類型轉(zhuǎn)化為String類型toString()?
var str = myNum.toString();
String類型轉(zhuǎn)化為Number類型int.parse()?
int myNum = int.parse(str)或者double.parse(str)(最好使用double年枕,因?yàn)槿绻鹲tr是double字符串的話,只能使用double.parse(),如果str是空字符串’’的話會(huì)報(bào)錯(cuò)乎完,所以可以使用try{} cache(err){}
其他類型轉(zhuǎn)化為bool類型
isEmpty:判斷字符串是否為空if(str.isEpmty){字符串是空字符串}?
Number類型:使用== if(myNum == 1 || myNum == null || myNum.isNaN){}或者其他的條件運(yùn)算符
bool?
true和false
條件判斷?
if 語(yǔ)句 == 判斷類型以及值是否相等
數(shù)組:
List:打印后是[]
1熏兄、var list =[’123’,‘456’];list.length list[0]?
2、var list = new List();list.add(‘a(chǎn)a’);list.add(‘bb’);
3树姨、定義List指定類型:var list = new List();list.add(‘a(chǎn)a’);?
常用屬性:
length:長(zhǎng)度list.length
reversed:翻轉(zhuǎn)打印后是(),var newList = list.reversed.toList();轉(zhuǎn)化為反轉(zhuǎn)后的數(shù)組
isEmpty:是否為空l(shuí)ist.isEmpty
isNotEmpty:是否不為空l(shuí)ist.isNotEmpty
常用方法:
add:增加 list.add(‘a(chǎn)a’); 只能增加一個(gè) 修改當(dāng)前數(shù)組
addAll:拼接數(shù)組list.addAll([‘a(chǎn)a’,‘bb’])修改當(dāng)前數(shù)組
indexOf:查找傳入具體值? list.indexOf(‘a(chǎn)a’);返回aa的索引值摩桶,查找不到返回-1
remove:刪除傳入具體值list.remove(‘a(chǎn)a’);修改當(dāng)前數(shù)組
removeAt:刪除傳入索引值list.removeAt(1);修改當(dāng)前數(shù)組
fillRange:修改list.fillRange(start,end,‘a(chǎn)aa’)修改當(dāng)前數(shù)組List list =[‘a(chǎn)’,‘b’,‘c’]list.fillRange(1,3,’d’)修改之后的就是[‘a(chǎn)’,‘d’,‘d’]
insert(index,value):指定位置插入list.insert(0,‘d’)修改當(dāng)前數(shù)組
insertAll(index,list):指定位置插入list.insert(0,[‘a(chǎn)’,‘b’,‘c’])
toList():其他類型轉(zhuǎn)化為L(zhǎng)ist?
join():List轉(zhuǎn)化成字符串var str = list.join(‘,’);返回字符串
split():字符串轉(zhuǎn)化成List List list = str.split(‘,’);返回?cái)?shù)組
forEach:list.forEach((value){print(value);print(“$value”);});
map:用于修改集合里面的數(shù)據(jù)List list=[1,2,3];var newList = list.map((value){return value * 2;})print(newList.toList())
where:var newList=list.where((value){return value > 2;})print(newList.toList())返回[3]
any:判斷l(xiāng)ist里面有沒有滿足條件的數(shù)據(jù)返回bool var f=list.any((value){return value > 2;})只要集合里面有滿足條件的就返回true
every:判斷l(xiāng)ist里面有沒有滿足條件的數(shù)據(jù)返回bool var f=list.every((value){return value > 2;})集合里面所有的元素都要滿足條件才返回true,否則返回false
數(shù)組截取sublist(0,3)
集合
Set:主要功能就是去除數(shù)組重復(fù)內(nèi)容打印的話是{}帽揪,Set是沒有順序且不能重復(fù)的集合硝清,所以不能通過索引去獲取值?
var set = new Set();set.add(‘a(chǎn)’);? set.add(‘a(chǎn)’);打印之后還是{‘a(chǎn)’}通過set.toList()可以轉(zhuǎn)化為數(shù)組
通過set.addAll(list).toList()返回去重后的數(shù)組
forEach:set.forEach((value)=>{print(“$value”)});
map:同數(shù)組
where:同數(shù)組
any:同數(shù)組
every:同數(shù)組
字典
Map:key必須要加引號(hào),定義Map也可以指定類型
1转晰、var person = {“name”:“張三”,“age”: 12,“work”: list}? person[“name”]
2芦拿、var person = new Map();person[“name”]=“里斯”;person[“age”]=12;person[“work”]=list;
常用屬性
keys:獲取所有的key值map.keys返回的是(),可以使用mao.keys.toList()轉(zhuǎn)化為數(shù)組[]
values:獲取所有的value值map.values同上
isEmpty:是否為空map.isEmpty
isNotEmpty:是否不為空map.isNotEmpty
常用方法
remove(key):刪除指定key的數(shù)據(jù)map.remove(‘key’)修改當(dāng)前的map
addAll({}):合并映射查邢,給映射內(nèi)增加屬性map.addAll({“work”:“工作”})
containsValue:查看映射內(nèi)的值返回true/false map.containsValue(“工作”);
forEach:map.forEach((key,value){print(key);print(“$value”);});
map:同數(shù)組
where:同數(shù)組
any:同數(shù)組
every:同數(shù)組
判斷數(shù)據(jù)類型
is:if(str is String){} else if(str is int){} else{}
常量:
const:值不變蔗崎,一開始就得賦值
final:可以開始不賦值,只能賦值一次扰藕;而final不僅有const的編譯時(shí)常量的特性缓苛,最重要的是他是運(yùn)行時(shí)常量,即在運(yùn)行時(shí)第一次使用前才初始化邓深。也就是可以使用final a = new DateTime.now();
循環(huán)語(yǔ)句
++(自增運(yùn)算符) - -(自減運(yùn)算符)
for:for(int i = 0;i < 10;I++){} for(var item in myList){}
while未桥、do while
函數(shù)、方法
1芥备、自定義方法
返回類型 方法名稱(參數(shù)1,參數(shù)2,…) {}
1>可選參數(shù)?
定義一個(gè)可選參數(shù)的方法:可選參數(shù)放在后面冬耿,可以有多個(gè)
String printUserInfo(String name,[int age,String work]){if(age == null){return“”;}return“姓名是$name年齡是$age工作是$work”}調(diào)用print(“你好”)
2>默認(rèn)參數(shù)
定義一個(gè)默認(rèn)參數(shù)的方法:可選參數(shù)放在后面,可以有多個(gè)示例门躯,默認(rèn)參數(shù)放在可選參數(shù)里面并且放在前面
String printUserInfo(String name,[int age = 30,String work]){if(age == null){return“”;}return“姓名是$name年齡是$age工作是$work”}調(diào)用print(“你好”,20)
3>命名參數(shù)?
使用{},除非有默認(rèn)參數(shù)淆党,否則是必傳的String printUserInfo(String name,{int age = 30,String work}){if(age == null){return“”;}return“姓名是$name年齡是$age工作是$work”}調(diào)用print(“你好”,age:20,work:”工作”)
4>把方法當(dāng)參數(shù)的方法
1>>fun2(fn1);2>>匿名方法fn2((value){print(value)});
2、箭頭函數(shù)
=>只有一行代碼可以使用剪頭函數(shù) => print(‘a(chǎn)’) 或者{ print(‘a(chǎn)’)} 內(nèi)部語(yǔ)句后面不需要加分號(hào)其他的每個(gè)語(yǔ)句后面必須要加分號(hào)讶凉;如果有return的話可以不寫return染乌,系統(tǒng)默認(rèn)return
var newList=list.map((value)=>value>2?value*2:value)
3、匿名函數(shù)
map方法就是
var printNum =(int n){print(123);}? 調(diào)用printNum(20);
4懂讯、自執(zhí)行方法
((){
print(‘我是自執(zhí)行方法’);? ?
})()
((Int n){
print(‘我是自執(zhí)行方法$n’);
})(12)
5荷憋、方法的遞歸
一個(gè)方法調(diào)用自己
var sum = 0;fn(int n){sum+=n;if(n==0){return;}. fn(n-1)}
6、閉包
全局變量:常駐內(nèi)存褐望,影響全局
局部變量:不常駐內(nèi)存勒庄,會(huì)被垃圾機(jī)制回收串前,不影響全局
閉包:常駐內(nèi)存,并且不影響全局
fn(){
var a = 123;//常駐內(nèi)存实蔽,而且不影響全局
retun(){
a++;
print(a);
}
}
var b = fn();b();b();b();打印出來是124 125 126
7荡碾、類、對(duì)象
特性:封裝局装、繼承坛吁、多態(tài)
Dart所有的東西都是對(duì)象,所有的對(duì)象都繼承自O(shè)bject類
Dart是一門使用類和單即成的面向?qū)ο笳Z(yǔ)言铐尚,所有的對(duì)象都是類的實(shí)例拨脉,并且所有的類都是Object的子類,一個(gè)類通常由屬性和方法組成宣增。
1>定義的類是放在main函數(shù)外面的
Person {
String _p;//私有屬性
String name=“張三”;
int age=23;
void getInfo(){
print(“$name——$age”);
print(“${this,name}——${this,age}”);//推薦寫法
}
void setInfo(int age){
this.age = age;
}
void _run(){
print(‘這是一個(gè)私有方法’);
}
String getP(){
//間接訪問
retun this,_name;
}
//默認(rèn)構(gòu)造函數(shù)玫膀,在實(shí)例化的時(shí)候觸發(fā)
Person(int age){
print(‘這是構(gòu)造函數(shù)’);
this.age = age;
}
或者
//默認(rèn)構(gòu)造函數(shù),在實(shí)例化的時(shí)候觸發(fā)爹脾,需要在后面添加分號(hào)帖旨,跟上面的是一致效果
Person(this,dage);
//命名構(gòu)造函數(shù)
Person.now(int age){
print(‘我是明明夠構(gòu)函數(shù)’);
this.age = age;
}
// getter方法,沒有()
get area{
print(this.age);
return age;
}
// setter方法
set area(int value){
this.age = value;
}
}
main(){
Person p = new Person(20);
print(p.name);
p.getInfo();
p.setInfo(20);
p.area;//調(diào)用get方法
p.area = 30;//調(diào)用set方法
}
2>構(gòu)造函數(shù) 如上
Dart里面構(gòu)造函數(shù)可以寫多個(gè)誉简,但是默認(rèn)構(gòu)造函數(shù)只能寫一個(gè)碉就,命名構(gòu)造函數(shù)可以寫多個(gè)
3>類單獨(dú)抽離成文件
直接把Person的代碼寫到單獨(dú)文件夾
使用的時(shí)候直接引用 import ‘文件地址不用./’
4>私有屬性 私有方法
首先我們需要把類抽離為單獨(dú)的文件夾,其次在前面添加_ 內(nèi)部使用的話也得添加_? 比如this._name;
5>類中的getter和setter方法
6>初始化列表
用于構(gòu)造函數(shù)
實(shí)例化之前類的內(nèi)部賦值
比如在類的內(nèi)部的構(gòu)造函數(shù)里面
Person():name=“張三”,age=12{}
7>靜態(tài)成員
使用static 關(guān)鍵字來實(shí)現(xiàn)靜態(tài)屬性和靜態(tài)方法
靜態(tài)方法不能訪問非靜態(tài)成員
非靜態(tài)方法可以訪問靜態(tài)成員:內(nèi)部使用靜態(tài)屬性的時(shí)候直接使用屬性名稱name闷串,使用非靜態(tài)屬性的時(shí)候最好使用this.name瓮钥,訪問靜態(tài)方法的話直接使用getInfo()
調(diào)用靜態(tài)屬性和靜態(tài)方法使用類名來調(diào)用Person.age;Person.setInfo();
8>操作符
? 條件運(yùn)算符(了解)Person p;? p?.printInfo(); 此時(shí)不能打印,如果p初始化烹吵,就能調(diào)用方法
as類型轉(zhuǎn)換? var p =‘’;p = new Person();(p as Person).pringInfo();強(qiáng)制類型轉(zhuǎn)換
Is類型判斷if(p is Person)判斷變量類型
.. 級(jí)聯(lián)操作(連綴)記椎锵ā!@甙巍锈津!就是一下執(zhí)行多個(gè)操作
Person p = new Person();
p..name=“李四”
? ..age=30
? ..printInfo();
9>類的繼承
子類使用extends關(guān)鍵詞來繼承父類
子類會(huì)繼承父類里面可見的屬性和方法,但是不會(huì)繼承構(gòu)造函數(shù)
子類能復(fù)寫父類的方法
class Person {
String name;
int age;
Person(this.name,this.age);
void printInfo(){
print(‘${this.name}——${this.age}’);
}
void run(){
print(‘run’);
}
}
class Web extends Person {
String sex;
//能繼承父類里面的屬性
//不能繼承構(gòu)造函數(shù)凉蜂,所以需要我們自己寫
//給父類的默認(rèn)構(gòu)造函數(shù)傳參數(shù)琼梆,同時(shí)也可以給命名構(gòu)造函數(shù)傳參super.xxx(name,age)
Web(String name,num age,String sex): super(name,age){
this.sex = sex;
}
//復(fù)寫標(biāo)示符 每一個(gè)復(fù)寫方法 都加一次 可寫可不寫,建議寫
@override
//子類中復(fù)寫父類的方法窿吩,調(diào)用的是子類的方法
void run(){
super.run();//調(diào)用父類方法
print(‘子類跑’);
}
}
使用:Web w = new Web(‘張三’茎杂,12,‘男’);
8、抽象類纫雁、多態(tài)煌往、接口
1>抽象類:Dart中抽象類主要用于定義標(biāo)準(zhǔn),子類可以繼承抽象類轧邪,也可以實(shí)現(xiàn)抽象類接口
抽象類通過abstract 關(guān)鍵字來定義
Dart中的抽象方法不能用abstract聲明刽脖,Dart中沒有方法體的方法我們稱為抽象方法
如果子類繼承抽象類羞海,必須得實(shí)現(xiàn)里面的抽象方法
如果把抽象類當(dāng)作接口實(shí)現(xiàn)的話必須得實(shí)現(xiàn)抽象類里面定義的所有屬性和方法
抽象類不能被實(shí)例化,只有他的子類可以
extends和implements的區(qū)別:
如果要復(fù)用抽象類里面的方法曲管,并且要用抽象方法約束子類的話我們就用extends繼承抽象類
如果只是把抽象類當(dāng)作標(biāo)準(zhǔn)的話我們就用implements實(shí)現(xiàn)抽象類
抽象類:是不能實(shí)例化的
abstract class Animal {
eat(); // 抽象方法却邓,沒有方法體
printInfo(){
print(‘普通方法’);
}
}
class dog extends Animal {
//必須實(shí)現(xiàn)
@overide
eat(){
print(‘小狗在吃骨頭’);
}
}
2>多態(tài)
允許將子類類型的指針賦值給父類類型的指針,同一個(gè)函數(shù)調(diào)用會(huì)有不同的執(zhí)行效果
子類的實(shí)例賦值給父類的引用
多態(tài)就是父類定義一個(gè)方法不去實(shí)現(xiàn)翘地,讓繼承他的子類去實(shí)現(xiàn)申尤,每個(gè)子類都有不同的表現(xiàn) 如上面的抽象類的例子的Animal和Dog
3>接口
Dart也有接口
Dart的接口沒有interface關(guān)鍵字定義接口癌幕,而是普通類或抽象類都可以作接口被實(shí)現(xiàn)同樣適用implements關(guān)鍵字進(jìn)行實(shí)現(xiàn)
如果實(shí)現(xiàn)的類是普通類衙耕,會(huì)將普通類和抽象中的屬性的方法全部需要重新復(fù)寫一邊
而因?yàn)槌橄箢惪梢远x抽象方法,普通類不可以勺远,所以一般如果要實(shí)現(xiàn)java接口那樣的方式橙喘,一般使用抽象類,建議使用抽象類定義接口胶逢。
只有抽象方法厅瞎,不寫公用方法
abstract class Db { //當(dāng)作接口接口:就是約定、規(guī)范
String uri;
add(String data);
save();
delete();
}
// 定義其他類 實(shí)現(xiàn)接口初坠,必須要實(shí)現(xiàn)所有的方法和屬性
class Mysql implements Db {
@override
String uri;
@override
add(String data){
print(data);
print(this.uri);
}
@override
save(){
}
@override
delete(){
}
Mysql(this,uri);
}
main(){
Mysql s = new Mysql(‘uri’);
s.add(‘data’);
//或者
Mysql s = new Mysql();
s.uri =‘123.123.123.123’;
s.add(‘data’);
}
9和簸、Dart中一個(gè)類實(shí)現(xiàn)多個(gè)接口以及Dart中的Mixins
一個(gè)類實(shí)現(xiàn)多個(gè)接口
class C implements A,B {實(shí)現(xiàn)接口所有的屬性以及方法}
Dart中的Mixins
中文意思就是混入,就是在淚中混入其他功能
在Dart中可以使用mixins實(shí)現(xiàn)類似多繼承的功能
因?yàn)閙ixins使用的條件碟刺,隨著Dart版本一直在變锁保,這里講的是Dart2.x中使用mixins的條件
1>作為mixins的類只能繼承自O(shè)bject,不能繼承其他類
2>作為mixins的類不能有構(gòu)造函數(shù)
3>一個(gè)類可以mixins多個(gè)mixins類
4>mixins絕不是繼承半沽,也不是接口爽柒,而是一種全新的特性
實(shí)現(xiàn)類似多繼承
A和B是mixins而且是普通的類,只能直接繼承自O(shè)bject(比如A不能繼承Person類)者填,不能有構(gòu)造函數(shù)
class C with A,B {里面有A和B的所有的屬性和方法}
class C extends Person with A,B{ //此時(shí)C繼承自Person同時(shí)mixinsA和B
//此時(shí)Person類里面有構(gòu)造函數(shù)浩村,C類必須要實(shí)現(xiàn)此構(gòu)造函數(shù)
C(string name,num age):super(name,age);
}
如果A和B中有同樣的方法,則后面的方法替換前面的方法 比如 with A,B 調(diào)用的就是B的方法占哟,如果是with B,A則使用的是A的方法心墅。
如果繼承中也有同樣的方法,同樣是后面的替換前面的
C is A以及C is B以及C is C以及C is Person都是true
10榨乎、范型 范型方法 范型類 范型接口
1>范型:解決類 接口 方法的復(fù)用性怎燥,以及對(duì)不特定數(shù)據(jù)類型的支持(類型校驗(yàn))
2>范型方法:
需求,函數(shù)傳入什么類型谬哀,返回什么類型刺覆,并支持類型校驗(yàn),使用范型 使用T
T getData(T value){return value}對(duì)傳入類型校驗(yàn)史煎,以及對(duì)返回類型校驗(yàn)
getData(T value){return value}只對(duì)傳入類型校驗(yàn)谦屑,不對(duì)返回類型校驗(yàn)
調(diào)用getData(‘你好’);檢查傳入類型和返回類型都是String
3>范型類:
集合List范型類的用法
List也是范型List list = new List();只能添加String的類型
案例:寫一個(gè)范型類驳糯,要求List里面可以增加int類型的數(shù)據(jù),也可以增加String類型的數(shù)據(jù)
class PrintClass<T> {
List list=new List();
void add(T value){
this.list.add(value);
}
}
使用:
要求只傳入String
PrintClass p = new PrintClass();p.add(“你好”);
要求只傳入int
PrintClass p = new PrintClass();p.add(123);
4>范型接口
abstract class Cache {getKey(String key);void setByKey(String key,T value)}
案例:實(shí)現(xiàn)功能:有文件緩存氢橙、和內(nèi)存緩存酝枢,內(nèi)存緩存和文件緩存按照接口的約束實(shí)現(xiàn)
定義一個(gè)范型接口約束實(shí)現(xiàn)他的子類必須有g(shù)etByKey(key)和setByKey(key,value)
要求setBykey的時(shí)候的value的類型和實(shí)例化子類的時(shí)候指定的類型一致
abstract class Cache<T> {
getData();
void setByKey(String key,T value);
}
class FileCache<t> implements Cache<T> {
@override
getData(){
return null;
}
@override
void setByKey(String key,T value){
print(‘我是文件’);
}
}
class MemoryCache<T> implements Cache<T> {
@override
getData(){
return null;
}
@override
void setByKey(String key,T value){
print(‘我是緩存’);
}
}
使用
MemoryCache m = new MemoryCache();
m.setByKey(“index”,“我是首頁(yè)緩存”);
11、Dart中的庫(kù) 自定義庫(kù) 系統(tǒng)庫(kù) 第三方庫(kù)
在Dart中悍手,庫(kù)的使用時(shí)候通過import關(guān)鍵字引入
library指令可以創(chuàng)建一個(gè)庫(kù)帘睦,每一個(gè)Dart文件都是一個(gè)庫(kù),即使沒有使用library指令來指定
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.flutter-io.cn/packages
https://pub.dartlang.org/flutter/
需要在自己項(xiàng)目根目錄新建一個(gè)pubspec.yaml
在pubspec.yaml文件 然后配置名稱坦康、描述竣付、依賴等信息
然后運(yùn)行pub get獲取包下載到本地
項(xiàng)目中引入庫(kù)import‘package:http/http.dart’as http;看文檔使用
async和await
只有async方法才能使用await關(guān)鍵字調(diào)用方法
如果調(diào)用別的async方法必須使用await關(guān)鍵字
async是讓方法變成異步
await是等待異步方法執(zhí)行完成
例如
void main()async {
var result = await testAsync();
}
testAsync()async {
return“hello”;
}
庫(kù)沖突之后的重命名
比如Person1和Person2中都有一個(gè)Person類,則如下處理
庫(kù)里面只引用部分功能
使用關(guān)鍵字 show 和 hide滞欠,導(dǎo)入庫(kù)中的某一些方法
關(guān)鍵自part和export?