Dart基础 Dart变量声明-var 1 2 3 4 5 6 7 8 void main(List <String > args) { var age = 20 ; print (age); age =21 ; print (age); var age1= "测试1" ; print (age1); }
语法: var 变量名=值/表达式;
注意:当声明的变量类型第一次以后不能再更改其类型,例如:上述代码中不能将age在下面赋值 String类型的值
Dart常量声明-const 1 2 3 4 5 6 7 8 9 10 11 void main(List <String > args) { const num =3.1415926 ; print (num ); num =100 ; const length = 2 * num *10 ; print (length); var num1=3.1415926 ; const num2=num1; }
Dart常量声明-final 1 2 3 4 5 void main(List <String > args) { final time = DateTime .now(); print (time); }
用法与const一样的
final与const的区别是 final是在运行时不可修改,const是编译时确定不可以修改
Dart中的常用数据类型 基本数据类型我就不写了只写一些不太相同的地方,重点集中于动态数据类型
String 属性名 = ‘文本内容$变量名’; 或String 变量名=’文本内容${变量名}’
数值类型: int,double
布尔类型: bool
列表类型: List
映射类型: Map
Dart中的列表类型-List
场景 :当一个变量需要存储多个值的时候,可以使用列表类型List
需求 :一个班级的学生用List存储,支持对学生的查找、新增、删除、循环
语法 :List 属性名 = [‘学生1’, ‘学生2’];
1 2 3 4 void main(List <String > args) { List students = ["张三" , "李四" , "王五" ]; print (students); }
输出结果:
Dart中的列表类型-List的常用操作方法
在尾部添加-add(内容)
在尾部添加一个列表-addAll(列表)
删除满足内容的第一个-remove(内容)
删除最后一个-removeLast()
删除索引范围内数据-removeRange(start,end)
Dart中的列表类型-List的常用操作方法和属性
循环-forEach((item) {});
是否都满足条件-every((item) { return 布尔值 });
筛选出满足条件的数据-where((item) { return 布尔值 });
列表的长度(属性)-length
最后一个元素(属性)-last
第一个元素(属性)-first
是否为空(属性)-isEmpty
Dart中的字典类型-Map Dart中的字典类型-Map的常用操作方法
循环-forEach
在添加一个字典-addAll
是否包含某个key-containsKey
删除某个key-remove
清空-clear
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 void main(List <String > args) { Map <String , String > transMap = {"hello" : "你好" , "world" : "世界" }; transMap.forEach((key, value) { print ('$key ,$value ' ); }); transMap.addAll({"fine" : "很好" }); transMap.containsKey("fine" ); transMap.remove("fine" ); transMap.clear(); }
Dart中的动态类型-dynamic和var的区别 区别对比
dynamic : 运行时可自由改变类型,无编译检查,方法和属性直接调用
var : 根据初始值进行推断类型,确定类型后类型确定,有编译检查,仅限推断的属性和方法
代码示例 1 2 3 4 5 6 7 void main(List <String > args) { var text = 1 ; text.toDouble(); dynamic text1 = 1 ; text1.startsWith("" ); }
Dart的空安全机制 空安全特性
可空类型 : 使用 ? 标记变量可以为 null
安全访问 : 使用 ?. 操作符安全访问可能为 null 的对象的方法或属性
非空断言 : 使用 ! 操作符告诉编译器变量一定不为 null(需谨慎使用)
空合并操作符 : 使用 ?? 提供默认值
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 void main(List <String > args) { String? userename = null ; userename?.startsWith("新" ); userename!.startsWith("xin" ); String displayName = userename ?? "默认用户" ; print (displayName); }
Dart中的函数
场景 :当一个功能需要被重复使用的时候,可以使用函数
需求 :一个班级的学生用List存储,支持对学生的查找、新增、删除、循环
语法 :void 函数名(参数1,参数2){ 函数体 }
1 2 3 4 5 6 7 8 void main(List <String > args) { int add(int a,int b){ return a+b; } int result = add(1 ,2 ); print (result); }
注意:返回值类型可省略,Dart会自动推断类型为dynamic
可选位置参数 特点 :可选位置参数必须位于必传参数后面,采用中括号包裹
语法 :函数名(String a, [String? b...])
传递方式 :按照顺序传递
适用场景 :参数少且顺序固定时
1 2 3 4 5 6 7 8 9 10 11 void main(List <String > args) { int add(int a,int b,[int? c]){ return a+b+(c??0 ); } int result = add(1 ,2 ); print (result); int result2 = add(1 ,2 ,3 ); print (result2); }
可选命名参数 特点 :可选命名参数采用大括号包裹,可按任意顺序传递
语法 :函数名(String a, {String? b, int? c})
传递方式 :函数名(a: '值', b: '值')
适用场景 :参数多且顺序不固定时
1 2 3 4 5 6 7 8 9 10 11 12 void main(List <String > args) { bool isNewName(String name, {bool? isNew}) { return isNew == true && name.startsWith("新" ); } bool result = isNewName("张三" ); print (result); bool result2 = isNewName("新张三" , isNew: true ); print (result2); }
匿名函数 特点 :可以声明一个没有名称的函数赋值给变量,进行调用
语法 :Function 变量名 = () {};
注意 :函数的类型使用Function来声明
箭头函数 特点 :当函数体只有一行代码时,可以使用箭头函数编写
语法 :函数名() => 代码逻辑
注意 :使用箭头函数可以省略return关键字
代码示例 :
1 2 3 4 5 6 main(List <String > args) { int add(int a, int b) => a + b; int result = add(1 , 2 ); print (result); }
Dart中的类 类的定义 定义 :Dart语言中,类(class)是面向对象编程的核心,类包含属性和方法来定义对象的行为和状态
需求 :定义一个Person类,属性包括姓名、年龄、性别,包括学习的方法
定义类语法 :class Person{属性方法}
实例化对象 :Person 变量 = Person();
属性和方法 :变量.属性/方法()
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Person { String name; int age; String gender; Person(this .name, this .age, this .gender); void study() { print ('$name 正在学习' ); } } void main(List <String > args) { Person person = Person('张三' , 18 , '男' ); print (person.name); print (person.age); print (person.gender); person.study(); }
构造函数 Dart中类的构造函数-默认构造函数 定义 :实例化对象的时候,使用构造函数直接给对象中的属性赋值
常见分类 :默认构造函数、命名构造函数、构造函数的语法糖
定义语法 :
1 2 3 4 5 class 类名 { 类名(可选命名参数) { } }
实例化语法 :
1 Person p = new Person(属性: 值);
代码示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Person { String? name = "" ; int? age = 0 ; String? sex = "男" ; Person({String? name, int? age, String? sex}) { this .name = name; this .age = age; this .sex = sex; } void study() { print ("$name 在学习" ); } }
Dart中类的构造函数-命名构造函数 定义 :构造函数可以采用命名的方式,返回一个实例化对象
定义语法 :
1 2 3 4 5 class 类名 { 类名.构造函数名(可选命名参数) { } }
实例化语法 :
1 Person p = Person.构造函数名(属性: 值);
注意 :默认构造函数和命名构造函数可同时存在
代码示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 class Person { String? name = "" ; int? age = 0 ; String? sex = "男" ; Person({String? name, int? age, String? sex}) { this .name = name; this .age = age; this .sex = sex; } Person.withName(String name) { this .name = name; } void study() { print ("$name 在学习" ); } } void main(List <String > args) { Person p1 = Person(name: "张三" , age: 18 , sex: "男" ); Person p2 = Person.withName("李四" ); p1.study(); p2.study(); } #### Dart中类的构造函数-构造函数语法糖 **定义**:同名构造函数和命名构造函数都支持简写写法 **语法**: ```dart class 类名 { 类名({ this .属性1 , this .属性2 }); 或 类名.命名函数({ this .属性1 , this .属性2 }); }
代码示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Person { String? name; int? age; String? sex; Person.createPerson({this .name, this .age, this .sex}); void study() { print ('$name 在学习' ); } } void main(List <String > args) { Person p = Person.createPerson(name: '张三' ); p.study(); Person pp = Person.createPerson(name: '张三' ); pp.study(); }
私有属性和公有属性 公有属性 :提供自身或者其他外部文件和类使用的属性和方法
私有属性 :仅供自身使用的属性和方法,其他外部文件和类无法访问
语法 :私有属性以下划线开头,如_name,其余均为公有属性
代码示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 class Person { String? name; int? age; String? _sex; Person({this .name, this .age, String? sex}) { _sex = sex; } void study() { print ('$name 在学习' ); } void _privateMethod() { print ('这是一个私有方法' ); } void showSex() { print ('性别: $_sex ' ); _privateMethod(); } } void main(List <String > args) { Person p = Person(name: '张三' , age: 18 , sex: '男' ); print (p.name); print (p.age); p.study(); p.showSex(); }
Dart中类的继承 继承的定义 定义 :继承是拥有父类的属性和方法
特点 :Dart属于单继承,一个类只能拥有一个直接父类,子类拥有父类所有的属性和方法
语法 :class 类名 extends 父类
重写 :子类可通过@override注解重写父类方法,扩展其行为
注意 :子类不会继承父类构造函数,子类必须通过super关键字调用父类构造函数确保父类正确初始化
super语法 :子类构造函数(可选命名参数): super({参数})
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void main(List <String > args) { Child c = Child(name: '张三' , age: 18 ); c.sayHello(); } class Parent { String? name; int? age; Parent({this .age,this .name}); void sayHello(){ print ('Hello, my name is $name , I am $age years old.' +'I am a parent.' ); } } class Child extends Parent { Child({String? name,int? age}):super (name: name,age: age); @override void sayHello(){ super .sayHello(); print ('Hello, my name is $name , I am $age years old.' +'I am a child.' ); } }
Dart中类的多态 多态的定义 定义 :Dart中的多态是指同一操作作用于不同的对象,可以产生不同的执行效果
场景 :微信和支付宝都遵循同样支付接口,但实现逻辑不同,即同一个支付操作拥有不同的支付效果
实现方式 :
继承和方法重写
抽象类和接口
多态示例-继承和方法重写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class BasePay { void Pay() { print ("基础支付功能" ); } } class WXPay extends BasePay { @override void Pay() { super .Pay(); print ("微信支付" ); } } class AliPay extends BasePay { @override void Pay() { super .Pay(); print ("支付宝支付" ); } } void main(List <String > args) { BasePay P = WXPay(); P.Pay(); BasePay pay = new AliPay(); pay.Pay(); }
多态示例-抽象类和接口实现 方式 :使用abstract关键字声明一个抽象类(没有实现体)
方式 :使用implements关键字继承并实现抽象类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 abstract class PayBase { void pay(); } class WxPay implements PayBase { @override void pay() { print ("微信支付" ); } } class AliPay implements PayBase { @override void pay() { print ("支付宝支付" ); } } void main(List <String > args) { PayBase p = WxPay(); p.pay(); }
Dart中类的混入 混入的定义 定义 :Dart允许在不使用传统继承的情况下,向类中添加新的功能
方式 :
使用mixin关键字定义一个对象
使用with关键字将定义的对象混入到当前对象
特点 :一个类支持with多个mixin,调用优先级遵循”后来居上”原则,即后混入的会覆盖先混入的同名方法
需求 :让一个学生类和一个老师类都拥有唱歌的方法
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 mixin Singing { void sing() { print ('正在唱歌' ); } } class Student { String? name; Student(this .name); } class Teacher { String? name; Teacher(this .name); } class SingingStudent extends Student with Singing { SingingStudent(String name) : super (name); } class SingingTeacher extends Teacher with Singing { SingingTeacher(String name) : super (name); } void main(List <String > args) { SingingStudent student = SingingStudent('张三' ); student.sing(); SingingTeacher teacher = SingingTeacher('李四' ); teacher.sing(); }
Dart中异步编程-事件循环 事件循环的介绍 介绍 :Dart是单线程语言,即同时只能做一件事,遇到耗时任务就会造成程序阻塞,此时需要异步编程
定义 :Dart采用单线程+事件循环的机制完成耗时任务的处理
事件循环的执行顺序
执行同步代码
执行微任务队列
执行事件队列
结束
微任务队列 :Future.microtask()
事件队列 :Future、Future.delayed()、I/O操作(文件、网络)等
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void main(List <String > args) { Future future = Future((){ return "Hello Future" ; }); future.then((value){ Future(() => "task1" ); }).then((onValue){ Future(() => "task2" ); }).then((onValue){ Future(() => "task3" ); }).catchError((onError){ print ("出现错误" ); }); }
Dart中异步编程-Future-async/await async/await的介绍 介绍 :除了通过then/catchError的方式,还可以通过async/await来实现异步编程
特点 :await总是等到后面的Future执行成功,才执行下方逻辑,async必须配套await出现
语法 1 2 3 4 5 6 7 8 函数名() async { try { await Future(); } catch (error) { } }
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void main(List <String > args) async { print ('开始执行' ); String result = await fetchData(); print ('获取到数据: $result ' ); print ('执行完毕' ); } Future<String > fetchData() { return Future.delayed(Duration (seconds: 2 ), () { return '模拟网络请求获取的数据' ; }); }