Dart 语言简述
Dart是一種“結(jié)構(gòu)化的web編程”語言,Dart編程語言在所有現(xiàn)代瀏覽器和環(huán)境中提供高性能。Dart是谷歌開發(fā)的計算機編程語言,后來被ECMA認定為標準。
Dart重要的概念:
1、所有的東西都是對象。無論是變量、數(shù)字、函數(shù)等都是對象。所有的對象都是實例。所有的對象都繼承自內(nèi)置的Object類。這點類似于JAVA語言的“一切皆為對象”。
2、程序中指定數(shù)據(jù)類型使得程序合理地分配內(nèi)存空間,并幫助編譯器進行語法檢查。但是,指定類型不是必須的。Dart語言是弱數(shù)據(jù)類型。
3、Dart代碼在運行前解析。指定數(shù)據(jù)類型和編譯時的長列,可以提高運行速度。
4、Dart程序有統(tǒng)一的程序入口:main()。這一點與JAVA、C/C++語言相像。
5、Dart沒有public、protected和private的概念。私有特性通過變量或函數(shù)加下下劃線來表示。
6、Dart的工具可以檢查出警告信息(warning)和錯誤信息(errors)。警告信息只是表明代碼可能不工作,但是不會妨礙程序運行。錯誤信息可以是編譯時的錯誤,也可能是運行時的錯誤。編譯時的錯誤將阻止程序運行,運行時的錯誤將會以異常(execption)?的方式呈現(xiàn)。
7、Dart支持anync/await異步處理。
8、關(guān)鍵字
| abstract 2 | dynamic 2 | implements 2 | show 1 |
| as 2 | else | import 2 | static 2 |
| assert | enum | in | super |
| async 1 | export 2 | interface 2 | switch |
| await 3 | extends | is | sync 1 |
| break | external 2 | library 2 | this |
| case | factory 2 | mixin 2 | throw |
| catch | false | new | true |
| class | final | null | try |
| const | finally | on 1 | typedef 2 |
| continue | for | operator 2 | var |
| covariant 2 | Function 2 | part 2 | void |
| default | get 2 | rethrow | while |
| deferred 2 | hide 1 | return | with |
| do | if | set 2 | yield 3 |
避免使用這些單詞作為標識符。但是,如有必要,標有上標的關(guān)鍵字可以是標識符:
-
帶有上標1的單詞是上下文關(guān)鍵字,僅在特定位置有意義。它們在任何地方都是有效的標識符。
-
帶有上標2的單詞是內(nèi)置標識符。為了簡化將JavaScript代碼移植到Dart,這些關(guān)鍵字在大多數(shù)地方都是有效的標識符,但它們不能用作類或類型名稱,也不能用作導入前綴。
-
帶有上標3的單詞是與Dart 1.0發(fā)布后添加的異步支持相關(guān)的有限保留字。不能在任何被標記async,async*或sync*標記的函數(shù)體中使用await或yield作為標識符。
表中的所有其他單詞都是保留字,不能是標識符。
Dart語言的常用庫
| 包名 | 概述 |
| dart:async | 異步編程支持,提供Future和Stream類 |
| dart:collection | 對dart:core?提供更多的集合支持 |
| dart:convert | 不同類型(JSON、UTF-8)間的字符編碼、解碼支持 |
| dart:core | Dart語言內(nèi)建的類型、對象以及dart語言核心的功能 |
| darr:html | 網(wǎng)頁開發(fā)用到的庫 |
| dart:io | 文件讀寫I/O相關(guān)操作的庫 |
| dart:math | 數(shù)字常量及函數(shù),提供隨機數(shù)算法? |
| dart:svg | 事件和動畫的矢量圖像支持 |
其中三個開發(fā)庫的使用頻率最高:
dart:core? 核心庫,包含strings、numbers、collections、errors、dates、URIs等。
dart:html? 網(wǎng)頁開發(fā)里DOM相關(guān)的一些庫。
dart:io? I/O命令行使用的I/O庫。
dart:core庫時Dart語言初始已經(jīng)包含的庫,其他的任何庫在使用前都需要加上import語句。
變量與基本數(shù)據(jù)類型:
?在Dart里,變量聲明使用var關(guān)鍵字。在Dart語言里一切且為對象,所以如果沒有將變量初始化,那么它的默認值為null。
1、常量和固定值
常量及固定值在開發(fā)中很常見。如果定義的變量不會變化,可以使用final或const來指明。const是一個編譯時的常量;final的值只能被設(shè)定一次。
例如:第一行代碼設(shè)置了一個常量,如果第二行進行重新賦值,那么將引發(fā)異常。
final username = "張三"; //定義了一個常量 //username = "李四"; //會引發(fā)一個錯誤通過對const類型做四則運行將自動得到一個const類型的值。下面代碼會得到一個常量,計算圓的面積:
const pi = 3.1415926; const area = pi * 100 * 100;可以通過const來創(chuàng)建常量的值,就是說const[]本身是構(gòu)造函數(shù),示例代碼如下:
final stars = const []; const buttons = const [];2、基本數(shù)據(jù)類型
Dart語言常用的基本數(shù)據(jù)類型包括:Number、String、Boolean、List、Map。
(1)Number類型:包括int整型,?double浮點型
int和double類型都是num類型的子類。int類型不能包含小數(shù)點。num類型包括的操作有:+,-,*,/以及位移操作>>。num類型包括的常用方法有:abs、ceil和floor。
(2)String類型:字符串類型
可以使用三個單引號或雙引號來定義多行的String類型,在Flutter中我們專門用來表示大文本塊。
var s1 = ''' var s2 = """ //請注意這是一個用三個引號包裹起來的字符串,可以用來添加多行數(shù)據(jù)(3)Boolean類型
Dart是強bool類型檢查,只有bool類型的值是true才被認為是true。有的語言里0是false,大于0是true。在Dart語言里則不是,值必須為true或者false。
var sex = "男"; if(sex){print("你的性別是!" + sex); }上面的示例代碼編譯不能正常通過,因為sex變量是一個字符串,不是使用條件判斷語句,必須用bool類型才可以。
(4)List類型
在Dart語言中,具有一系列相同類型的數(shù)據(jù)稱為List對象。Dart里的List對象類似于JavaScript語言的數(shù)組Array對象。
var list = [1, 2, 3];(5)Map類型
Map類型將key和value關(guān)聯(lián)在一起,也就是鍵值對。像其他支持Map的編程語言一樣,key必須是唯一的。
var week = {"Monday" : "星期一","Tuesday" : "星期二","Wednesday" : "星期三","Thursday" : "星期四","Friday" : "星期五","Saturday" : "星期六","Sunday" : "星期日", };//也可以使用Map對象的構(gòu)造函數(shù)Map()來創(chuàng)建Map對象var week = new Map();week[Monday] = "星期一";week[Tuesday] = "星期二";week[Wednesday] = "星期三";week[Thursday] = "星期四";week[Friday] = "星期五";week[Saturday] = "星期六";week[Sunday] = "星期日";添加新的key-value對,再給week添加一個值,注意,其中0為鍵不是數(shù)組的下標索引:week['0'] = '星期一';
檢查key是否在Map對象中:assert(week['Monday'] == null);
使用length來獲取key-value對的數(shù)量,現(xiàn)在我們調(diào)用length輸出長度為8,原因是剛才后面又添加了一個數(shù)據(jù)(0),代碼如下:print(week.length);
3、函數(shù)
Dart是一個面向?qū)ο蟮恼Z言,所以函數(shù)也是對象,函數(shù)屬于Function對象。
函數(shù)可以像參數(shù)一樣傳遞給其他函數(shù),這樣便于做回調(diào)處理。
//判斷兩個字符串是否相等 bool equal(String str1, String str2) {retrue str1 == str2; }(1)可選參數(shù)
將參數(shù)使用中括號[]括起來,用來表明是可選位置參數(shù)。
例如:總共傳入了三個參數(shù),其中name和sex是必須傳入的參數(shù),from參數(shù)可以不傳,代碼如下:
//獲取用戶信息 String getUserInfo(String name, String sex, [String from]) {var info = '$name 的性別是 $sex';if(from != null){info = ‘$info來自$from’; } return info; }void test(){pring(getUserInfo(‘小王’, '男')); }(2)參數(shù)默認值
如果參數(shù)指定了默認值,當不傳入值時,函數(shù)里會使用這個默認值。如果傳入了值,則用傳入的值取代默認值。通常參數(shù)的默認值為null。
改造上面獲取用戶信息的例子,給from參數(shù)賦上默認值,代碼如下:
//獲取用戶信息 使用等號= 來設(shè)置默認位置參數(shù) String getUserInfo(String name, String sex, [String from = '中國']) {var info = '$name 的性別是 $sex';if(from != null){info = ‘$info來自$from’; }return info; }void test(){pring(getUserInfo(‘小王’, '男')); }?調(diào)用上面的test()方法可以輸出“小王的性別是男來自中國”。
(3)main函數(shù)
Flutter應用程序必須要有一個main函數(shù),和其他語言一樣作為程序的入口函數(shù)。?
如下代碼表示應用要啟動MyApp類:void main() => runApp(MyApp());
(4)函數(shù)返回值
在Dart語言中,函數(shù)的返回值有如下特點:
- 所有的函數(shù)都有返回值
- 如果沒有指定函數(shù)返回值,則默認的返回值是null
- 沒有返回值的函數(shù),系統(tǒng)會在最后添加隱式的return語句
4、運算符
Dart支持各種類型的運算符,并且其中的一些操作符還能進行重載。完整的操作符如下表
| 一元后綴 | expr++ expr-- () [] . ?. |
| 一元前綴 | -expr !expr ~expr ++expr --expr |
| 乘法類型 | * / % ~/ |
| 加法類型 | + - |
| 移動位運算 | << >> |
| 與位運算 | & |
| 異或位運算 | ^ |
| 或位運算 | | |
| 關(guān)系和類型測試 | >= <= > < as is is! |
| 等式 | == != |
| 邏輯與 | && |
| 邏輯或 | || |
| 條件 | expr1 ? expr2 : expr3 |
| 級聯(lián) | .. |
| 賦值 | = *= /= ~/= %= += -= <<= >>= &= ^= |= ??= |
使用運算符時可以創(chuàng)建表達式,以下是運算符表達式的一些示例: a++ a-- a + b a = b a == b expr ? a : b a is T
注意使用運算符時的順序。在運算符表中,操作符的優(yōu)先級由上到下逐個減小,上面行內(nèi)的操作符優(yōu)先級大于下面行內(nèi)的操作符。例如,“乘法類型”操作符%的優(yōu)先級比"等階"操作符==要高,而==操作符的優(yōu)先級又比"邏輯與"操作符&&要高。
//使用括號來提高可讀性 if((n % i == 0) && (d & i == 0)); //難以閱讀,但是和上面等階 if(n % i == 0 && d & i == 0);提示:對于二元運算符,其左邊的操作數(shù)將會決定使用的操作符的種類。例如:當你使用一個Vector對象以及一個Point對象時,aVector + aPoint使用的+是由Vector所定義的。
(1)算術(shù)運算符
?Dart支持常用的算術(shù)運算符:
| 操作符 | 含義 |
| + | 加 |
| - | 減 |
| -expr | 一元減號,也命名為負號(使后面表達式的值反過來) |
| * | 乘 |
| / | 除 |
| ~/ | 返回一個整數(shù)值的除法 |
| % | 取余,除法剩下的余數(shù) |
| ++var | var=var+1?表達式的值為var+1 |
| var++ | var=var+1?表達式的值為var |
| --var | var=var-1?表達式的值為var-1 |
| var-- | var=var-1?表達式的值為var |
示例代碼如下:
assert(3 + 6 == 9); assert(3 - 6 == -3); assert(3 * 6 == 18); assert(7 / 2 == 3.5); //結(jié)果是浮點型 assert(5 ~/2 == 2); //結(jié)果是整形 assert(5 % 2 == 1); //求余數(shù)var a, b; a = 0; b = ++a; //在b獲得其值之前自增a assert(a == b); //1 == 1 a = 0; b = a++; //在b獲得值后自增a assert(a != b); //1 != 0 a = 0; b = --a; //在b獲得其值之前自減a assert(a == b); //-1 == -1 a = 0; b = a--; //在b獲得值后自減a assert(a != b); //-1 != 0(2)關(guān)系運算符
| 操作符 | 含義 |
| == | 等于 |
| != | 不等于 |
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
有時候需要判斷兩個對象是否相等,請使用==運算符。
(3)類型測試操作符
as、is和is!?操作符在運行時用于檢查類型非常方便,含義如下:
| 操作符 | 含義 |
| as | 類型轉(zhuǎn)換 |
| is | 當對象時相應類型時返回true |
| is! | 當對象不是相應類型時返回true |
如果obj實現(xiàn)了T所定義的接口,那么obj?is T?將返回true。
使用as操作符可以把一個對象轉(zhuǎn)換為制定類型,前提是能夠轉(zhuǎn)換。轉(zhuǎn)換之前用is判斷一下更保險。如下代碼:
if(user is User){//類型檢測user.name = 'Flutter'; }//如果能確定user時User的實例,則可以通過as直接簡化代碼: (user as User).name = ‘Flutter’;注意:上面兩段代碼并不相等,如果user的值為null或者不是一個User對象,則第一段代碼不會做出任何事情,第二段代碼會報錯。
(4)賦值操作符
可以使用 = 運算符賦值。要僅在變量為null時賦值,請使用 ??= 運算符。如下代碼所示:
//賦值給a a = value; //如果b為空,則將值分配給b;否則b保持不變 b ??= value;諸如+=之類的復合賦值運算符將操作符與賦值相結(jié)合。以下是復合賦值運算符的工作方式:
| 復合賦值符 | 等式表達式 |
| a op b | a = a op b |
| a += b | a = a + b |
| a -= b | a = a - b |
(5)邏輯運算符
可以使用邏輯運算符反轉(zhuǎn)或組合布爾表達式。邏輯運算符如下所示:
| 操作符 | 含義 |
| !expr | 反轉(zhuǎn)以下表達式(將false更改為true,反之亦然) |
| || | 邏輯或 |
| && | 邏輯與 |
示例代碼如下:
if(!expr && (test == 1 || test == 8)) {...... }(6)位運算符
通常我們指位運算為<<?或 >>?移動位運算,通過操作位的移動來達到運算的目的,而&、|、^、~expr也是操作位來達到運算的目的。
| 操作符 | 含義 |
| & | 與 |
| | | 或 |
| ^ | 異或 |
| ~expr | 一元位補碼(0s變?yōu)?s;1s變?yōu)?s) |
| << | 左移 |
| >> | 右移 |
示例代碼如下:
final value = 0x22; final bitmask = 0x0f; assert((value & bitmask) == 0x02); //與 assert((value & -bitmask) == 0x20); //與非 assert((value | bitmask) == 0x2f); //或 assert((value ^ bitmask) == 0x2d); //異或 assert((value << 4) == 0x220); //左移 assert((value >> 4) == 0x02); //右移(7)條件表達式
Dart由兩個運算符,可用來簡明地評估可能需要if-else語句的表達式。如下代碼即為一種條件表達式,也可以稱為三元表達式,如果條件為真,返回expr1,否則返回expr2.
condition ? expr1 : expr2;第二種如下表示,如果expr1為非空,則返回其值;否則,計算并返回expr2的值。
expr1 ?? expr2;(8)?級聯(lián)操作
級聯(lián)操作用兩個點(..)表示,可對同一對象執(zhí)行一系列操作。類似于Java語言里點點點處理或JavaScript里的Promise的then處理。級聯(lián)操作主要的目的是為了簡化代碼。
querySelector('#btnOK') { //獲取一個id為btnOK的按鈕對象..text = '確定' //使用它的成員..classes.add('ButtonOKStyle');..onClick.listen((e) => window.alert('確定')); }//相當于var button = querySelector('#btnOK'); button.text = '確定'; button.classes.add(' ' ButtonOKStyle ' '); button.onClick.listen((e) => window.alert('確定'));第一個方法調(diào)用querySelector,返回一個按鈕對象,然后再設(shè)置它的文本為“確定”,再給這個按鈕添加一個樣式叫“ButtonOKStyle”,最后在監(jiān)聽單擊事件,事件彈出一個顯示“確定”的Alert。
注意:嚴格來說,級聯(lián)的“雙點”符號不是運算符。這只是Dart語法的一部分。
5、流程控制語句
Dart語言的流程控制語句如下:if和else、for(循環(huán))、while和do-while(循環(huán))、break和continue、switch和case、assert(斷言)、try-catch和throw。
(1)if和else
Dart支持if及else的多種組合。
String today = 'Monday'; if(today == 'Monday') {print('今天是星期一'); }else if(today == 'Tuesday') {print('今天是星期二'); }else {print('今天是個好日子'); } //輸出'今天是星期一',條件語句走到第一條判斷就停止了。(2)for(循環(huán))
下面舉例說明for循環(huán),首先定義了一個字符串“Hello Dart”,然后使用for循環(huán)向message變量里寫入5個同樣的字符“!”。
var message = new StringBuffer('Hello Dart'); for(var i = 0; i < 5; i ++) {message.write(i); } print(message); //輸出“Hello Dart!!!!!”,注意值是字符串向尾部添加的。//除了常規(guī)的for循環(huán)外,針對可以序列化的操作數(shù),可以使用forEach()方法,當不關(guān)心操作數(shù)的當前下標時,forEach()方法師很簡便的。 var arr = [0, 1, 2, 3, 4, 5, 6]; for(var v in arr){print(v); } //按序列輸出 0 1 2 3 4 5 6(3)while和do-while(循環(huán))
下面舉例說明while循環(huán),其中定義了一個變量temp,temp在循環(huán)體內(nèi)自動加1,當條件(temp<5)不滿足時會推出循環(huán),代碼如下:
var _temp = 0; while(_temp < 5) {print('這是一個循環(huán):' + (_temp).toString());_temp ++; }var _temp = 0; do{print(‘這是一個循環(huán):’ + (_temp).toString());_temp ++; }while(_temp < 5);//都輸出 //flutter:這是一個循環(huán):0 //flutter:這是一個循環(huán):1 //flutter:這是一個循環(huán):2 //flutter:這是一個循環(huán):3 //flutter:這是一個循環(huán):4(4)break和continue
break用來跳出循環(huán),改造前面的循環(huán)例子:
var arr = [0, 1, 2, 3, 4, 5, 6]; for(var v in arr){if(v == 2){break;} print(v); } //當v等于2的時候跳出循環(huán),所以輸出“0,1”。現(xiàn)在把break改為continuevar arr = [0, 1, 2, 3, 4, 5, 6]; for(var v in arr){if(v == 2){//break;continue;} print(v); } //改為continue后,當v等于2的時候只是跳出本次循環(huán),代碼還會繼續(xù)往下執(zhí)行,所以輸出結(jié)果是“0,1,3,4,5,6”(5)switch和case
Dart中switch/case語句使用==操作來比較整數(shù)、字符串或其他編譯過程中的常量,從而實現(xiàn)分支的作用。switch/case語句的前后操作數(shù)必須是相同類型的對象實例。每一個非空的case子句最后都必須跟上break語句。
String today = 'Monday'; switch(today) {case 'Monday' : print('星期一');break;case 'Tuesday' :print('星期二');break; }(6)assert(斷言)
Dart語言通過使用assert語句來中斷正常的執(zhí)行流程,當assert判斷的條件為false時發(fā)生中斷。assert判斷的條件是任何可以轉(zhuǎn)化為boolean類型的對象,即使是函數(shù)也可以。如果assert的判斷為true,則繼續(xù)執(zhí)行下面的語句;反之則會拋出一個斷言錯誤異常AssertionError。
//確定變量的值不為null assert(text != null);6、異常處理
異常是表示發(fā)生了意外的錯誤,如果沒有捕獲異常,引發(fā)異常的隔離程序?qū)⒈粧炱稹2⑶页绦驅(qū)⒔K止。
Dart代碼可以拋出并捕獲異常,但與Java相反,Dart的所有異常都是未檢查的異常。方法不聲明它們可能拋出那些異常,也不需要捕獲任何異常。
Dart提供了異常和錯誤類型以及許多預定義的子類型。當然,也可以定義自己的異常。然后,Dart程序可以拋出任何非空對象。
(1)拋出異常
下面是一個拋出或引發(fā)異常的例子:
throw FormatException('拋出一個FormatException異常');你也可以拋出任意對象:?
throw '數(shù)據(jù)非法!';提示:穩(wěn)定健壯的程序一定是做了大量異常處理的,所以建議你在編寫程序時盡量考慮到可能發(fā)生異常的情況。
(2)捕獲異常
你可以指定一個或兩個參數(shù)來捕獲異常(catch),第一個是拋出的異常,第二個是堆棧跟蹤(StackTrace?對象)。如下代碼所示:
try {//...}on Exception catch (e) {print('Exception details:\n $e');}catch (e, s) {pring('Exception details:\n $e');pring('Stack trace:\n $s');} //上面的代碼第一個catch用來捕獲異常詳細信息,第二個catch是堆棧跟蹤信息(3)Finally
要確保某些代碼能夠運行,無論是否拋出異常,請使用finally子句。如果沒有catch子句匹配異常,則異常在finally子句運行后傳播。如下面代碼所示,在最下面加上了finally語句:
try {//...}on Exception catch (e) {print('Exception details:\n $e');}catch (e, s) {pring('Exception details:\n $e');pring('Stack trace:\n $s');}finally {print('Do some thing:\n');}7、面向?qū)ο?/p>
Dart作為高級語言支持面向?qū)ο蟮暮芏嗵匦?#xff0c;并且支持基于mixin的繼承方式。基于mixin的繼承方式是指:一個類可以繼承自多個父類,相當于其他語言里的多繼承。所有的類都有同一個基類Object,這個特性類似于Java語言,Java所有的類也都是繼承自O(shè)bject,也就是說一切皆為對象。
使用new語句實例化一個類,如下所示:
//實例化了一個User類的對象user var user = new User('張三', 20);(1)實例化成員變量
定義一個User類,在里面添加兩個成員變量name和age,代碼如下:
class User{String name; //name成員變量String age; //age成員變量 }類定義中所有的變量都會隱式的定義setter方法,針對非空的變量會額外增加getter方法。實例化成員變量請參考如下代碼:
class User{String name; //name成員變量Int age; //age成員變量 } main() {var user = new User();user.name = '張三'; //相當于使用了name的setter方法user.age = 20; }(2)構(gòu)造函數(shù)
①常規(guī)構(gòu)造函數(shù)
構(gòu)造函數(shù)是用來構(gòu)造當前類的函數(shù),是一個特殊的函數(shù),函數(shù)名稱必須要和類名相同才行。如下代碼為User類添加了一個構(gòu)造函數(shù),函數(shù)里給User類的兩個成員變量初始化了值:
class User{String name;int age;User(String name, int age) {this.name = name;this.age =age;} }//this關(guān)鍵詞指向了當前類的實例,上面的代碼可以簡化為:class User{String name;int age;User(this.name, this.age); }②命名的構(gòu)造函數(shù)
使用命名構(gòu)造函數(shù)從另一類或現(xiàn)有的數(shù)據(jù)中快速實現(xiàn)構(gòu)造函數(shù),代碼如下:
class User {String name;int age;User(this.name, this.age);//命令構(gòu)造函數(shù) User.fromJson(Map json) {name = json['nage'];age = json['age'];} }③構(gòu)造函數(shù)初始化列表
除了調(diào)用父類的構(gòu)造函數(shù),也可以通過初始化列表在子類的構(gòu)造函數(shù)運行前來初始化實例的成員變量值。代碼如下:
class User {final String name;final int age;User(name, age): name = name,age = age; }main() {var p = new User('張三', 20); }(3)讀取和寫入對象
?get()和set()方法是專門用于讀取和寫入對象的屬性方法,每一個類的實例,系統(tǒng)都隱式地包含有g(shù)et()和set()方法。這和很多語言里的VO類相似。
例如,定義一個矩形的類,有上、下、左、右四個成員變量:top、bottom、left、right,使用get及set關(guān)鍵字分別對right及bottom進行獲取和設(shè)置值。代碼如下:
class Rectangle {num left;num top;num width;num height;Rectangle(this.left, this.top, this.width, this.height);//獲取right值num get right => left + width;//設(shè)置right值 同時left也發(fā)生變化set right(num value) => left = value - width;//獲取bottom值num get bottom => top + height;//設(shè)置bottom值 同時top也發(fā)生變化set bottom(num value) => value - height; }main(){var rect = new Rectangle(3, 4, 20, 15);print('left:' + rect.left.toString());print('right:' + rect.right.toString());rect.right = 30;print('更改right值為30');print(‘left:’ + rect.left.toString());print('right:' + rect.right.toString());print('top:' + rect.top.toString());print('bottom:' + rect.bottom.toString());rect.bottom= 50;print('更改bottom值為50');print('top:' + rect.top.toString());print('bottom:' + rect.bottom.toString()); } //對應的輸出為: //flutter: left:3 //flutter: right:23 //flutter: 更改right值為30 //flutter: left:10 //30-20 //flutter: right:30 //flutter: top:4 //flutter: bottom:19 //flutter: 更改bottom值為50 //flutter: top:35 //50-15 //flutter: bottom:50(4)重載操作
編寫一個例子,定義一個Vector向量類,編寫兩個方法分別用于重載加號以及減號,那么兩個向量相加,就表示它們的x值及y值相加,當兩個向量相減,就表示它們的x值及y值相減。
//定義一個向量類 class Vector {final int x;final int y;const Vector(this.x, this.y);//重載加號 + (a + b)Vector operator +(Vector v) {retrun new Vector(x + v.x, y + v.y);}//重載減號 - (a - b)Vector operator -(Vector v) {retrun new Vector(x - v.x, y - v.y);} }main() {//實例化兩個向量final v = new Vector(2, 3);final w = new Vector(2, 2);final r1 = v + w;print('r1.x=' + r1.x.toString() + ' r1.y=' + r1.y.toString());final r2 = v - w;print('r2.x=' + r2.x.toString() + ' r2.y=' + r2.y.toString()); }//上面輸出結(jié)果為: //flutter: r1.x=4 r1.y=5 //2+2 2+3 //flutter: r2.x=0 r1.y=1 //2-2 3-2(5)繼承類
繼承是面向?qū)ο缶幊碳夹g(shù)的一塊基石,因為它允許創(chuàng)建分等級層次的類。繼承就是子類繼承父類的特征和行為,使得子類對象(實例)具有父類的實例域和方法;或子類從父類繼承方法,使得子類具有父類相同的行為。Dart里使用extends關(guān)鍵字來創(chuàng)建一個子類,super關(guān)鍵字來制定父類。
?例子:定義一個動物類,動物具有吃和跑兩種能力。再定義一個人類,人類是屬于動物類的,人類不僅會吃和會跑,還會說、會學習。所以人類相當于動物類的一個擴展。具體代碼:
//動物類 class Animal {//動物會吃void eat() {print('動物會吃'); }//動物會跑void run() {print('動物會跑'); } } //人類 class Person extends Animal{//人類會說void say() {print('人類會說');}//人類會學習void study() {print('人類會學習');} } main() {print('實例化一個動物類');var animal = new Animal();animal.eat();animal.run();print('實例化一個人類');var person = new Person();person.eat();person.run();person.say();person.study(); } //輸出結(jié)果: //flutter:實例化一個動物類 //flutter:動物會吃 //flutter:動物會跑 //flutter:實例化一個人類 //flutter:動物會吃 //flutter:動物會跑 //flutter:人類會說 //flutter:人類會學習(6)抽象類
抽象類類似于Java語言中的接口。抽象類里不具體實現(xiàn)方法,只是寫好定義接口,具體實現(xiàn)留著調(diào)用的人去實現(xiàn)。抽象類可以使用abstract關(guān)鍵字定義類。
例子:定義一個抽象類叫DateBaseOperate,里面定義4個數(shù)據(jù)庫常用的操作方法“增刪改查”。再定義一個類命名為DateBaseOperateImpl繼承自DateBaseOperate用來實現(xiàn)抽象類里的方法。代碼如下:
//數(shù)據(jù)庫操作抽象類 abstract class DateBaseOperate {void insert(); //定義插入的方法void delect(); //定義刪除的方法void update(); //定義更新的方法void query(); //定義查詢的方法 }//數(shù)據(jù)庫操作實現(xiàn)類 class DateBaseOperateImpl extends DateBaseOperate {//實現(xiàn)了插入的方法void insert() {print('實現(xiàn)了插入的方法');}//實現(xiàn)了刪除的方法void delect() {print('實現(xiàn)了刪除的方法');}//實現(xiàn)了更新的方法void update() {print('實現(xiàn)了更新的方法');}//實現(xiàn)了查詢的方法void query() {print('實現(xiàn)了查詢的方法');} } main(){var db = new DateBaseOperateImpl();db.insert();db.select();db.update();db.query(); } //輸出結(jié)果為: //flutter:實現(xiàn)了插入的方法 //flutter:實現(xiàn)了刪除的方法 //flutter:實現(xiàn)了更新的方法 //flutter:實現(xiàn)了查詢的方法(7)枚舉類型
枚舉類型是一種特殊的類,通常用來表示相同類型的一組常量值。每個枚舉類型都用于一個index的getter,用來標記元素的元素位置。第一個枚舉元素的索引是0.
enum Color {red,green,blue }獲取枚舉類中所有的值,使用value常用:
List<Color> colors = Color.values;因為枚舉類型里面的每個元素都是相同類型,可以使用switch語句來針對不同的值做不同的處理,示例代碼如下:
enum Color {red,green,blue } //定義一個顏色變量 默認值為藍色 Color aColor = Color.blue; switch (aColor) {case Color.red:print('紅色');break;case Color.green:print('綠色');break;default: //默認顏色pring(aColor); //Color.blue }(8)Mixins
Mixins(混入功能)相當于多繼承,也就是說可以繼承多個類。使用with關(guān)鍵字來實現(xiàn)Mixins的功能。示例代碼如下:
class S {a() {print('S.a');} } class A {a() {print('A.a');}b() {print('A.b');} }class T = A with S;main(List<String> args) {T t = new T();t.a();t.b(); } //上面代碼從結(jié)果來看T具有了S及A兩個類的方法 //S.a //A.b8、泛型
泛型通常是為了類型安全而設(shè)計的,適當?shù)刂付ǚ盒皖愋蜁筛玫拇a,可以使用泛型來減少代碼重復。Dart中使用<T>的方式來定義泛型。
例如,如果想要List只包含字符串,可以將其聲明為list<String>。如下所示:
var names = new List<String>(); names.addAll(['張三', '李四', '王五']);(1)用于集合類型
泛型用于List和Map類型參數(shù)化:List:<type>? ? ? Map:<keyType, valueType>
例子:
var names = <String>['張三', '李四', '王五']; var weeks = <String, String>{'Monday' : '星期一',‘Tuesday' : '星期二','Wednesday' : '星期三','Thursday' : '星期四','Friday' : '星期五','Saturday' : '星期六','Sunday' : '星期日', };(2)在構(gòu)造函數(shù)中參數(shù)化
Map類型的例子如下:
var users = new Map<String, String>();9、庫的使用
(1)引用庫
通過import語句在一個庫中引用另一個庫的文件。需要注意以下事項:
- 在import語句后面需要接上庫文件的路徑。
- 對Dart語言提供的庫文件使用dart:xx格式。
- 第三方的庫文件使用package:xx格式。
import例子:
import 'dart:io'; import 'package:mylib/mylib.dart'; import 'package:utils/utils.dart';(2)指定一個庫的前綴
當引用的庫擁有相互沖突的名字,可以為其中一個或幾個指定不一樣的前綴。這與命名空間的概念比較接近。示例代碼如下:
import 'package:lib1/lib1.dart'; import 'package:lib2/lib2.dart' as lib2; //... Element element1 = new Element(); //使用lib1中的Element lib2.Element element2 = new lib2.Element(); //使用lib2中的Elementlib1/lib1.dart及l(fā)ib2/lib2.dart里都有Element類,如果直接引用就不知道具體引用那個Element類,所以代碼中把lib2/lib2.dart指定成lib2,這樣使用lib.Element就不會發(fā)生沖突。
(3)引用庫的一部分
如果只需要使用庫的一部分內(nèi)容,可以有選擇的引用,有如下關(guān)鍵字:
- show關(guān)鍵字:只引用一點。
- hide關(guān)鍵字:除此之外都引用。
示例代碼如下:
//導入foo import 'package:lib1/lib1.dart' show foo;//除了foo導入其他所有內(nèi)容 import 'package:lib1/lib1.dart' hide foo;10、異步支持
Dart語言是目前少數(shù)幾個支持異步操作的語言。一般使用async函數(shù)和await表達式實現(xiàn)異步操作。
Dart庫提供asynchronous功能,該功能提供接口來進行耗費時間的操作,比如文件讀寫、網(wǎng)絡請求。該功能返回Future或Stream對象。
可以通過如下的方式來獲取asynchronous功能返回的Future對象的值:
- 使用async函數(shù)和await表達式。
- 使用Future功能提供的API。
可以通過如下的方式來獲取asynchronous功能返回的Stream對象的值:
- 使用async和一個異步的循環(huán)(await?for)。
- 使用Stream的相關(guān)API。
下面的例子代碼使用了async或await異步處理,雖然代碼看起來像是同步處理的:await readFile()
必須在一個使用了async關(guān)鍵字標記后的函數(shù)中使用await表達式:
fileOperate () async {//讀取文件var file = await readFile();//其他處理 }11、元數(shù)據(jù)?
使用元數(shù)據(jù)給代碼添加更多的信息。元數(shù)據(jù)是以@開始的修飾符,在@后面接著編譯時的常量或調(diào)用一個常量構(gòu)造函數(shù)。目前Dart語言提供三個@修飾符:
(1)@deprecated被棄用的
(2)@override重寫
(3)@proxy代理
使用@voerride修飾符可以重寫父類方法。改造之前寫的例子,人類重寫eat方法,代碼如下:
//動物類 class Animal {//動物會吃void eat(){print('動物會吃');}//動物會跑void run(){print('動物會跑');} }//人類 class Person extends Animal {//人類會說void say(){print('人類會說');} //人類會學習void study(){print('人類會學習); }@override//人類也會吃void eat(){print('人類也會吃');} }main() {print('實例化一個動物類');var animal = new Animal();animal.eat();animal.run();print('實例化一個人類');var person = new Person();person.eat();person.run();person.say();person.study(); } //輸出結(jié)果是 //flutter:實例化一個動物類 //flutter:動物會吃 //flutter:動物會跑 //flutter:實例化一個人類 //flutter:人類也會吃 //flutter:動物會跑 //flutter:人類會說 //flutter:人類會學習元數(shù)據(jù)可以修飾library(庫)、class(類)、typedef(類型定義)、type?parameter(類型參數(shù))、constructor(構(gòu)造函數(shù))、factory(工廠函數(shù))、function(函數(shù))、field(作用域)、parameter(參數(shù))、variable?declaration(變量聲明)。
12、注釋
?Dart支持三種注釋類型:單行注釋、多行注釋、文檔注釋。
(1)單行注釋:以//開頭。從//開始到一行結(jié)束的所有內(nèi)容都會被Dart編譯器忽略。
(2)多行注釋:以/*開頭,以*/結(jié)束,之間的所有內(nèi)容都會被Dart編譯器忽略。
(3)文檔注釋:以/**或///開頭。
轉(zhuǎn)載于:https://www.cnblogs.com/joe235/p/11152040.html
總結(jié)
- 上一篇: 现代3D图形编程学习-关于本书(译)
- 下一篇: 并发编程--多线程