Dart安裝與語法,爲之後的flutter做鋪墊

因爲flutter 是用的dart語法,我的以爲,工欲善其事,必先利其器,知道了由什麼寫的,後面就不難啦。設計模式

dart 安裝

Mac 安裝bash

一.安裝homebrew後執行閉包

brew tap dart-lang/dart
brew install dart            // 安裝穩定版

brew install dart --devel    // 安裝開發版
安裝完成後查看路徑
複製代碼

二.配置環境變量,便可在全局使用dart

brew info dart
配置環境變量,找到~/.bash_profile,添加一句,路徑爲剛剛查到的
export PATH=/usr/local/Cellar/dart/2.1.0/bin:$PATH
複製代碼

三.在vscode中使用dartide

新建文件,eg:main.dart函數

安裝code runner擴展程序,每次點擊右上角的三角形圖標便可執行dart編譯。這個擴展程序蠻好用的,能夠支持多種語言的編譯。ui

dart 語法

入口文件,固定寫法

void main(){}
複製代碼

變量與常量

使用var聲明變量,可賦予不一樣的值this

未初始化時,默認值爲nullspa

使用final聲明一個只能賦值一次的變量設計

使用const聲明常量code

使用const聲明的必須是編譯期常量

數據類型

共有Number、String、Boolean、List(列表)、Map(鍵值對)、Runs(不經常使用)、Symbols(不經常使用)

num

分爲 包括 int(整型)和double(浮點型)

num a = 10; // num  型能夠指定浮點和整型
  a =10.2;
  
  int b = 10;
  // b = 11.11;  // ❌ 具體的類型聲明後不能再賦予爲浮點型了
複製代碼

數值型操做

  • 運算符
+,-、*、/ 、 ~/(取整)、%(取餘)
複製代碼
  • 經常使用屬性
isNaN(是不是非數字)、isEven(是不是偶數)、isOdd(是不是奇數)
複製代碼
  • 經常使用方法
abs() // 絕對值
round() // 向下取整
floor()  // 向上取整
ceil() 
toInt() 、toDouble()
複製代碼

String 字符串

使用單引號或雙引號建立字符串

使用三個引號建立多行字符串

字符串操做

  • +(字符串鏈接) *(字符串倍數) ==(字符串是否相等) [] (字符串的下標)
  • 插值表達式${}
  • 屬性 length、 isEmpty、isNotEmpty
  • 方法 contains() subString() startsWith() endsWith() indexOf() lastIndexOf()
  • toLowerCase() toUpperCase() trim() trimLeft() trimRight() split() replace()

bool 布爾型

bool  aa =  true; 
複製代碼

List 列表

建立

  • 建立list var list = [1,2,3];
  • 建立不可變的list var list = const [1,2,4];
  • 構造函數 var list = new List()

list操做

  • length
  • add() insert()
  • remove() clear()
  • indexOf() lastIndexOf()
  • sort() 排序 sublist() 截取元素
  • shuffle() asMap()轉爲map型 forEach()

Map 鍵值對

建立

  • 建立map var map={'name':'wang','age':18};
  • 建立不可變的map var map = const {'name':'wang','age':18};
  • 構造函數 var list = new Map()

map 操做

  • length,[]
  • isEmpty(), isNotEmpty()
  • keys,values
  • containsKey() containsValue()
  • remove()
  • forEach()

dynamic 動態類型

var list = new List<dynamic> ();
  list..add('1')..add(2)..add(true);
  print(list); // ['1',2,true] 動態添加不一樣類型的值
複製代碼

運算符

算數運算符

  • + - *  /  ++ -- 

關係運算符

  • > < >= <= != 
  • 判斷內容相同使用 ==
String str1 ='123';
  String str2 = '123';
  print(str1 == str2); //true
複製代碼

邏輯運算符

  • ! && ||

賦值運算符

  • 基礎 = ??= 存在運算符
  • 複合 += -= *= /= %= ~/=
int m;
  m ??= 10;
  print(m);  //10,若初始值有值則??=後面的值不賦值,若無值則賦值
  
  int m = 5;
  m ??= 10;
  print(m); // 5
複製代碼

條件表達式

  • 三元表達式
  • ??運算符
String cc;
  String cd ='dart';
  String c = cc ?? cd;
  print(c); //'dart'  若是前面有值就用前面的沒值就用後面的
複製代碼

控制語句

if

  • if if..else if ...else if..else

for

  • for for..in
var list =['咱們','要永遠','在一塊兒'];
  for(var index = 0;index<list.length;index++){
    print(list[index]);
  }
  for(var item in list){
    print(item);
  }
複製代碼
  • whild do...while
  • break 終止循環 continue 跳出當前循環
  • switch...case

方法

  • 格式 返回類型 方法名 (傳參1,傳參2){ 方法體 return 返回值}
void main(List args){} //第一個表示返回類型,void 表達不須要返回類型,括號裏面表示傳參

複製代碼

方法特性

  • 方法也是對象
  • 返回值類型 參數類型能夠省略
  • 箭頭語法,只適合一個表達式 => expr
  • 方法都有返回值,若沒有指定,默認返回null
String getPerson(String name,int age){
  return 'name=$name;age=$age';
}
複製代碼

可選參數

  • {param1,param2,param3}
  • [param1,param2,param3]
printPerson('niuxialing', 18);    //name=niuxialing age=18 gender=null
printPerson('fff',19,gender:'girl');  //name=fff age=19 gender=girl
printPerson1('xiaoling',18,'boy');  //name=xiaoling age=18 gender=boy
  
printPerson(name,age,{String gender}){
  print('name=$name age=$age gender=${gender}'); // 花括號參數能夠隨意組合傳過去
}

printPerson1(name,[int age,String gender]){
  print('name=$name age=$age gender=${gender}'); // 中括號必須按照順序傳
}
複製代碼

正常參數必須在可選參數的前面

默認參數

  • 使用= 在可選參數指定默認參數
  • 默認參數只能是編譯時常量

方法對象

  • 方法可做爲對象賦值給其餘變量
  • 可做爲參數傳遞給其餘方法
void main(){
   List list = ['i','am','a']; 
   print(listChange(list,times)); // 傳一個函數做爲參數
}
List listChange(List list,String times(String str)){  注意:參數定義了類型,函數下面也要定義類型,不然會報錯
  for(var index = 0; index < list.length;index++){
    list[index] = times(list[index]);
  }
  return list;
}


String times(String str){
  return str * 3;
}
複製代碼

匿名方法

  • 可賦值給變量。經過變量進行調用
  • 可在其餘方法中直接調用或傳遞給其餘方法
//方式一 賦值給變量調用
  var fun = (str){
    print('print hello -${str}');
  };
  fun('niuxiaoling');
  // 方式二 自執行
  ((){
    print('調用');
  })();
  // 方式三 在其餘方法中調用
  List listTimes(List list){
  var fun = (str){  // 匿名函數
    return str*3;
  };
  for(var index = 0; index<list.length;index++){
    list[index] = fun(list[index]);
  }
  return list;
}
複製代碼

閉包

  • 閉包是一個方法(對象)
  • 閉包定義在其餘方法的內部
  • 閉包能訪問外部方法內的局部變量,並持有其狀態
void main(){
 var f = fun();
 f();
}

fun(){
 var count = 0;
 return (){
   print('aa=$count');
 };
}
複製代碼

面向對象

類與對象

與Java 很類似

  • 經過class聲明一個類
  • 使用關鍵字new建立一個對象,new可省略
  • 全部對象都繼承與Object

屬性與方法

  • 屬性默認生成settergetter方法
  • 使用final聲明的屬性只有getter方法,就是說不能設置
  • 屬性和方法均可以經過.訪問
  • 方法不能被重載
  • 類名首字母必須大寫

類及成員可見性

  • Dart中的可見性以library(庫)爲單位
  • 默認狀況下,每一個dart文件就是一個庫
  • 使用下劃線—表示庫的私有性,只能在當前庫中使用,屬性和方法同理
  • 使用import導入庫

計算屬性

計算屬性是計算而來的,自己並不存儲值,計算屬性賦值是經過計算轉換到其餘實例變量上面的。

  • 重寫setget方法
  • get格式 返回值 get 屬性
void main(){
      print(rec.area); // 是屬性,不是方法
  }
  num get area{
    return width * height;
  }
複製代碼
  • set格式 set 屬性(){}
void main(){
     rec.area = 200;
      print(rec.width); //180
  }
  set area(value){
    width = value -20 ;
  }
複製代碼

構造方法

  • 若是沒有自定義構造方法,會有個默認構造方法
  • 若是存在自定義構造方法,默認構造方法無效
  • 構造方法不能重載
  • 格式 類名(){}
class Person{
    Person(){} //構造函數
}
複製代碼
  • 構造函數的2種賦值方法

方式一(語法糖經常使用 的)

class Person{
    String name;
    int age; final String gender;
    Person(this.name,this.age,this.gender); // 此時的初始化賦值在構造函數以前,因此能夠修改final 聲明的屬性
}
複製代碼

方式二

class Person{
  String name;
  int age;
  final String gender;
  Person(String name ,int age,String gender){
    this.name = name;
    this.age = age;
    this.gender = gender;  // 此時會報錯,由於final聲明的屬性不能修改
  }

  String work(){
    return '$name is $age,but he is working hard,he is a $gender';
  }
}
複製代碼

命名構造方法

void main(){
    var alice = Person.getName('alice');
}
class Person{
    String name;
    Person.getName(this.name);
}
複製代碼

常量構造方法

  • 若是類是不可變狀態,就能夠把對象定義爲編譯時常量
  • 使用const聲明構造方法,而且全部變量都爲final
  • 使用const 聲明對象,能夠省略
void main(){
    const a = Person('xiaoling',19);
}
class Person{
  final String name;
  final int age;
  const Person(this.name,this.age); // 必須前面加const
}
複製代碼

工廠構造方法

  • 相似於設計模式中的工廠模式
  • 在構造函數前面加關鍵字factory實現一個工廠構造方法
  • 在工廠構造方法中能夠返回對象
class Factory{
  final String name;
  factory Factory(String name){  //工廠構造方法能夠返回對象
    return Factory._inter(name);  // 返回對象
  }

  Factory._inter(this.name);   // 類私有的命名構造函數
}
複製代碼

初始化列表

  • 初始化列表在構造方法體以前執行
  • 使用逗號分隔初始化表達式
  • 初始化列表經常使用於設置final變量的值
void main(){
  var a = Person.mapValue({'name':'xoaling','age':19});
}
class Person{
  String name;
  int age;
  final String gender;
  Person.mapValue(Map map): name= map['name'],gender = map['gender']{
    this.age = map['age'];
  }
}
複製代碼

靜態成員

  • 使用static關鍵字實現類級別的變量和函數
  • 靜態成員不能訪問非靜態成員,非靜態能夠訪問靜態成員
  • 類中的常量須要使用static const來聲明
void main(List<String> args) {
  var page = new Page();
  page.scrollUp() //報錯
  Page.scrollDown();   // 能夠用類直接返回靜態方法
}
class Page{
  static const maxPage = 10; //常量必須加關鍵詞static
  static int currentpage = 1;

  static void scrollDown(){
    currentpage = 1;
    print('scrollDown...');
  }
  void scrollUp(){
    currentpage++;
    print('scrollUp...');
  }
}

複製代碼

對象操做符

  • 條件運算符 ?.
void main(List<String> args) {
  Person person = new Person();
  person?.work();  //如有這個屬性就執行,若沒有就什麼都不作
}

class Person{
  String name;
  int age; 
  void work(){
    print('working');
  }
}
複製代碼
  • 類型轉換 as
var person;
  person = '';
  person = new Person();
  (person as Person).work(); // 變量名賦值過多的狀況下,不知道類型具體是啥,須要進行類型轉換
複製代碼
  • 是不是指定類型 is is!
if(person is Person){
     person.work();
  }
複製代碼
  • 級聯操做符 ..
person..name='tom'
        ..age = 10
        ..work(); 
  一直執行,用分號結束
複製代碼

call 方法

  • 若是類實現了call()方法,則該類的對象能夠做爲方法使用
  • 名稱是call
void main(){
    var person = Person();
    peron('hah');  // name = hah
}
class Person{
  String name;
  int age; 
  String call(String name){
    return 'name = $name';
  }
}
複製代碼

高級進階 封裝、繼承、多態

繼承

  • 使用關鍵詞extends繼承一個類
  • 子類會繼承父類可見 的屬性和方法,不會繼承構造方法
  • 子類能夠複寫父類的方法 setter 和getter 方法
  • 單繼承,多態性
void main(){
  var student = new Student();
  print(student.isAudit);  //true
}
class Person{
  String name;
  int age;
  bool get isAudit => age>18;
  void run(){
    print('run,,');
  }
}

class Student extends Person{
  void study(){
    super.run();
    print('study....');
  }
  @override    // 重寫父類方法
  bool get isAudit => age>=10;
}
複製代碼

繼承中的構造方法

  • 子類的構造方法默認會調用父類中的無名無參構造方法
void main(){
  Student student = Student();

}
class Person{
  Person(){
    print('父類的構造方法');
  }
}
class Student extends Person{
  int age;
}
複製代碼
  • 若是父類沒有無名無參構造方法,則須要顯示調用父類構造方法
void main(){
  Student student = Student('tom');
}
class Person{
  String name;
  Person(this.name){
    print('父類的構造方法');
  }
  Person.widthName(this.name);
}
class Student extends Person{
  Student(String name) : super(name);
}
複製代碼

構造方法執行順序

  • 父類的構造方法在子類構造方法體開始執行的位置調用
  • 若是有初始化列表,初始化列表在父類構造方法以前執行,初始化列表與繼承用逗號隔開
class Student extends Person{
  int age;
  final String gender;
  Student(String name,String gender):  gender = gender,super.widthName(name);
}
複製代碼

抽象類

  • 抽象類使用關鍵字abstract表示。不能直接被實例化
  • 抽象方法不用abstract實現,無實現的
  • 抽象類能夠沒有抽象方法
  • 有抽象方法的必定要是抽象類

接口

  • 類和接口是統一的, 類就是接口
  • 每一個類都隱式的定義了一個包含全部實例成員的接口
  • 使用關鍵詞implements
  • 若是是複用已有類的實現,使用繼承(extends)
  • 若是隻是使用已有類的外在行爲,就使用接口(implements)

mixins

  • 相似於多繼承,是在多類繼承中重用一個類代碼的方式
  • 如有同一個方法,是看繼承的順序的,執行最後一個的方法
void main(List<String> args) {
  var teacher = new Teacher();
  teacher.study(); // teacher 同時擁有3個類的方法
}

class Student1{
  void study(){
    print('student1 study...');
  }
}
class Student2{
   void run(){
    print('student2 study...');
  }
}
class Student3{
   void singer(){
    print('student3 study...');
  }
}
// 若須要Teacher同時擁有上面3個學生的類,用繼承
class Teacher extends Student1 with Student2,Student3{

}
複製代碼
  • 做爲mixins的類不能有顯式聲明的構造方法

  • 做爲mixins的類只能繼承Object
  • 使用關鍵字with鏈接一個或多個mixin

操做符的覆寫

  • 覆寫操做符須要在類中定義
格式  返回類型 關鍵字operator (參數1,參數2){
    實現體
    return 返回值
}
複製代碼
  • 若是覆寫== ,還須要覆寫對象的hasCode getter方法

可覆寫的操做符

[]= > < | / ~/ ^ >> << % [] * & >= <=

void main(List<String> args) {
  var person1 = new Person(19);
  var person2 = new Person(30);
  print(person1>person2);
  print(person1['age']);
  print(person1 == person2);
}

class Person{
  int age;
  Person(this.age);

  bool operator >(person){    //定義操做符>
    return this.age > person.age;
  }

  int operator [](String str){  //定義操做符[]
    if('age' == str){
      return this.age;
    }
    return 0;
  }

}
複製代碼

枚舉

  • 枚舉是一種有窮序列集的數據類型
  • 使用關鍵字enum定義一個枚舉
  • 經常使用於代替常量,控制語句等

枚舉特性

  • index 從0開始,依次累加
  • 不能指定原始值,即默認值
  • 不能添加方法
void main(){

  var colorbox = Colors.blue;
  print(colorbox.index);  // 獲取index
  switch(colorbox){
     case Colors.blue:
      print('blue');break;
     case Colors.green:
      print('green');break;
      case Colors.red:
      print('red');break;
  }
   
}
  enum Colors{
    red,
    green,
    blue
  }
複製代碼

泛型

  • dart中類型是可選的,可以使用泛型限定類型
  • 使用泛型能夠有效減小代碼的重複

泛型的使用

  • 類的泛型
在屬性上使用泛型
void main(){
  var a = new Type<int>();
  a.input(1);
  var b = new Type<String>(); // 在屬性上使用泛型
  b.input('sss');
}

class Type<T>{
  T element;
  void input(T element){
    this.element = element;
    print(this.element);
  }
}
複製代碼
void main(){
  var p1 = new Person();
  p1.input<int>(1);
  p1.input<String>('sss');
}
class Person{
  void input<T>(T element){
    if(T == int){
      print('只能輸入數字');
    }
    if(T == String){
      print('只能輸入字符串');
    }
  }
}
複製代碼
相關文章
相關標籤/搜索