但願在閱讀本文以前,你已經閱讀了:
Flutter之旅:Dart的基礎語法
Flutter之旅:從源碼賞析Dart面向對象編程
..
那Paint對象的設置來看:安全
---->[情景1:曾經的寫法]----
var paint = Paint();
paint.strokeCap = StrokeCap.round;
paint.style = PaintingStyle.stroke; //畫線條
paint.color = Color(0xffBBC3C5); //畫筆顏色
paint.isAntiAlias = true; //抗鋸齒
paint.filterQuality = FilterQuality.high; //抗鋸齒
---->[情景2:級聯的寫法]----
paint
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke //畫線條
..color = Color(0xffBBC3C5) //畫筆顏色
..isAntiAlias = true //抗鋸齒
..filterQuality = FilterQuality.high;
複製代碼
很簡潔,很高大上有木有,bash
?.
---->[情景1:普通調用]----
void main() {
var a = -5;
print(a.abs());//5
}
---->[情景2:普通調用前置空,會崩掉]----
var a = 5;
a=null;
print(a.abs());//NoSuchMethodError: The method 'abs' was called on null.
---->[情景3:?.調用不會崩掉,只返回null]----
var a = 5;
a = null;
print(a?.abs()); //null
複製代碼
is
、 is!
和as
var b=10;
print(b is String);//false
print(b is num);//true
print(b is! double);//true
String c="12315";
print((c as Comparable<String>).compareTo("a"));//-1 強制類型轉換
print((c as num).abs());//類型轉換異常
// type 'String' is not a subtype of type 'num' in type cast
複製代碼
import 'dart:math';//導入math內置庫
import 'package:flutter/material.dart';//根據文件系統路徑到包
複製代碼
as
關鍵字的使用當sin函數處於連個包中,而且兩個包都被導入,該怎麼辦微信
---->[utils/color_utils.dart]----
sin(double d){
}
---->[main.dart:5]----
import 'package:toly/utils/color_utils.dart';
import 'dart:math';
void main() {
sin(5);
}
---->[解決方案]----
import 'package:toly/utils/color_utils.dart' as myMath;
import 'dart:math';
void main() {
myMath.sin(5);
}
複製代碼
被隱藏的對象沒法被外界訪問異步
import 'package:toly/utils/color_utils.dart' show sin;//只顯示sin函數
import 'package:toly/utils/color_utils.dart' hide sin;//只隱藏sin函數
複製代碼
須要注意的是,Dart中沒有private,public,protected修飾符。 如何作到訪問權限控制,是個問題,默認是能夠被訪問的。async
---->[painter/person.dart]----
class Person{
String name;
int age;
Person(this.name,this.age);
say(){
print("my name is $name and i am $age years old.");
}
}
---->[main.dart]----
import 'package:toly/painter/person.dart';
void main() {
var toly = Person("toly", 25);
print(toly.age);//25
toly.say();//my name is toly and i am 25 years old.
}
複製代碼
Dart中規定,名稱前加下劃線能夠限制外部的訪問,以下_age。
方法名,文件名也是如此,不想對外暴露,前面加下劃線便可編程語言
---->[painter/person.dart]----
class Person{
String name;
int _age;
Person(this.name,this._age);
say(){
print("my name is $name and i am $_age years old.");
}
}
---->[main.dart]----
void main() {
var toly = Person("toly", 25);
toly.say();//my name is toly and i am 25 years old.
print(toly._age);//報錯
}
複製代碼
library
和export
關鍵字的使用這裏拿animation來舉例子,使用時導包:
import 'package:flutter/animation.dart';
在源碼中animation.dart只作了一個概括暴露的動做。ide
library animation;
export 'src/animation/animation.dart';
export 'src/animation/animation_controller.dart';
export 'src/animation/animations.dart';
export 'src/animation/curves.dart';
export 'src/animation/listener_helpers.dart';
export 'src/animation/tween.dart';
export 'src/animation/tween_sequence.dart';
複製代碼
Dart中的泛型和Java中很是類似,可讓類型變得安全,代碼更加優雅。函數
拿List類來講,在類定義時類名List後加了,在使用時List就能夠加一個類型。這樣的好處在於當你試圖添加其餘類型的數據到該List對象中時,會報錯。這樣就是的類型變得安全。post
---->[sky_engine/lib/core/list.dart:54]----
abstract class List<E> implements EfficientLengthIterable<E> {
---->[main.dart]----
void main() {
var languages=List<String>();//定義一個泛型爲String的列表
var odd=List<int>();//定義一個泛型爲int的列表
}
複製代碼
這並不算泛型特色,只是List,Map,Set快速初始化的寫法。
只不過看起來有些奇怪,這裏說一下,之後會常見這些寫法。
var languageList = <String>['Java', 'Dart', 'Kotlin'];
var markMap = <String,int>{'Java':100, 'Dart':80, 'Kotlin':60};
var languageSet = <String>{'Java', 'Dart','Kotlin'};
複製代碼
和Java語法一致,使用 來限定泛型的類型區域
以下面DiagnosticableNode中的泛型限定
class DiagnosticableNode<T extends Diagnosticable> extends DiagnosticsNode
複製代碼
在Dart中,方法也是能夠支持泛型的,好比下面的方法:
當調用var e = foo<int>("hello");
則會報錯,改成foo<String>
便可。
T add<T>(T t) {
return t;
}
複製代碼
關於異步,是一個挺大的話題,這裏簡單提一下,以後有詳細介紹。
Dart是一個單線程的編程語言,耗時操做會形成線程阻塞。
就至關於我在燒開水,水燒開以前都沒法進行其餘動做,這顯然是不合理的。
我徹底能夠在燒水的時候去掃地,等水開了再去處理,須要一個Future對象用於後續處理
class Water{
double temperature;
Water(this.temperature);
Future<Water> heat() {
temperature=100;
return Future<Water> (()=>this);
}
}
main(){
print("打開燒水開關");
Water(0).heat().then((water){
print('水已經燒開,如今溫度:${water.temperature},開始沖水');
});
print("掃地");
}
複製代碼
async
和await
關鍵字的使用async表示異步,await表示等待。注意在異步操做中返回的是Future對象
這個對象用於,後續的處理,好比水燒開後去沖水什麼的。
heat() async{
var water = await Water(0).heat();
print('水已經燒開,如今溫度:${water.temperature},開始沖水');
return water;
}
複製代碼
能夠卡看出,打開燒水開關後,接着是掃地,水燒開後再衝水,這就是異步操做。
更多的用法將在後面文件資源的讀取時作詳細闡述。
結果因爲
FormatException
異常,程序直接崩潰
這並非咱們想要的,直接崩潰會形成極差的用戶體驗。
void main() {
print(str2Num("a"));//FormatException: a
}
num str2Num(String str){
return num.parse(str);
}
複製代碼
這個和Java也是相似的,使用try...catch...finally代碼塊
這樣異常會經過日誌打印而且程序不會崩潰退出。 其中finally代碼塊中的語句無論異常與否,都會被執行
num str2Num(String str){
var result= 0;
try {
result= num.parse(str);
} catch (e) {
print('發生異常:$e');
} finally {
print('最終會被執行的代碼塊');
}
return result;
}
複製代碼
使用on關鍵字,能夠指定捕捉某一類異常。
num str2Num(String str){
var result= 0;
try {
result= num.parse(str);
} on FormatException catch (e) {
print('發生Format異常:$e');
} on IOException catch(e){
print('發生IO異常:$e');
} finally {
print('最終會被執行的代碼塊');
}
return result;
}
複製代碼
知道Dart支持多繼承,我是挺驚訝的,多繼承的問題在於父類構造可能被循環調用
經過下面的代碼能夠看出,是先調用父類的構造方法
class Living {
Living(){
print("Runner");
}
}
class Person extends Living{
Person(){
print("Person");
}
}
main(){
Person toly = Person();
}
---->[打印結果]----
Runner
Person
複製代碼
首先mixin是一個定義類的關鍵字。直譯出來是混入,混合的意思
Dart爲了支持多重繼承,引入了mixin關鍵字,它最大的特殊處在於:
mixin定義的類不能有構造方法
,這樣能夠避免繼承多個類而產生的父類構造方法衝突
class Living {
Living(){
print("Runner");
}
}
class Runner {
run(){
print("run");
}
}
class Walker{
walk(){
print("run");
}
}
class Person extends Living with Walker,Runner{
Person(){
print("Person");
}
}
main(){
Person toly = Person();
toly.run();
toly.walk();
}
複製代碼
使用方法很簡單,在
with
關鍵字後面將類名,這是該類就是mixin類
mixin就至關於將其餘類的能力混入到當前類,仍是挺厲害的。
惟一的限制就是mixin類沒法擁有構造函數,若是有構造方法會怎樣? 報錯唄。
使用class關鍵字定義的類是能夠當作mixin類使用的,好比上面的。
另外使用mixin關鍵字也能夠來定義mixin類,如:
mixin Walker{
walk(){
print("run");
}
}
複製代碼
惟一的區別在於,你是否肯定它是一個mixin類。
當你在mixin聲明的類中定義構造方法,會直接報錯。
取後混入的
class Runner {
go(){
print("Runner-go");
}
}
mixin Walker{
go(){
print("Walker-go");
}
}
class Person with Runner,Walker{
Person(){
print("Person");
}
}
main(){
Person toly = Person();
toly.go();//Walker-go
}
複製代碼
本文到此接近尾聲了,若是想快速嚐鮮Flutter,《Flutter七日》會是你的必備佳品;若是想細細探究它,那就跟隨個人腳步,完成一次Flutter之旅。
另外本人有一個Flutter微信交流羣,歡迎小夥伴加入,共同探討Flutter的問題,本人微信號:zdl1994328
,期待與你的交流與切磋。