var
dynamic
Object
dynamic和Object区别:
新建一个“1-variables.dart”,添加如下代码:
void main(){
dynamic d1 = "1234";
Object o1 = "1234";
d1.test();
o1.test();
}
d1.test();不会报错
o1.test();会报错
说明dynamic编译时不会检查,Object在编译时会检查。
总结如下:
//var声明一个初始化的变量,变量的类型不能再改变
var variable1 =
'hongxue'; //变量是一个引用。名字为 name 的变量引用了 一个内容为 “hongxue” 的 String 对象。
//variable1 = 123;//变量初始化后,name变量的类型被推断为String类型,其类型不能再改变
//dynamic和Object声明的变量初始化后,变量的类型仍可改变
dynamic variable2 = 'hongxue';
variable2 = 123;
// variable2.test();//调用不存在的test()方法,编译通过,运行报异常。编译阶段不检查类型
Object variable3 = 'hongxue';
variable3 = 123;
// variable3.test();//调用不存在的test()方法,编译不通过。编译阶段检查类型
//使用确定类型显示声明变量,变量的类型不能再改变
String name3;
name3 = 'hongxue';
// name3 = 123;//变量的类型不能再改变
//var:如果没有初始值,可以变成任何类型
//dynamic:动态任意类型,编译阶段不检查类型
//Object:动态任意类型,编译阶段检查检查类型
//区别:
//唯一区别 var 如果有初始值,类型被锁定
区别:
没有初始化的变量自动获取一个默认值为null
一切皆对象,对象的默认值为null
//没有初始化的变量默认值都是null。一切皆对象,对象的默认值是null
bool isEmpty;
assert(isEmpty == null);
共同点:
//1. 被final或者const修饰的变量,变量类型可以省略
final fVariable1 = 'hongxue';
// final String fVariable1 = 'hongxue';
const cVariable1 = 'hongxue';
// const String cVariable1 = 'hongxue';
//2. 被 final 或 const 修饰的变量无法再去修改其值。
// fVariable1 = 'damon';
// cVariable1 = 'damon';
//3. final或const不能和var同时使用。
// final var fVariable1 = 'hongxue';
// const var fVariable1 = 'hongxue';
区别(需要注意的地方):
//4. 如果是类级别常量,使用static const
DateTime; //可参照DateTime static const int monday = 1;
//5. const可以使用其他 const常量的值来初始化其值
const width = 100;
const height = 100;
const square = width * height;
//6. const赋值 申明可省略
const List clist = [1, 2, 3];
// const List clist = const [1, 2, 3];//dart 2之前,const赋值必须用const声明
//7. 可以更改非final,非const变量的值,即使它曾经具有const值
var varList = const [1, 2, 3];
final finalList = const [1, 2, 3];
const constList = [1, 2, 3];
varList = [1];
// constList = [1];
// finalList = [1];
//8. const导致的不可变性是可传递的
final List ls = [1, 2, 3];
ls[1] = 4;
print(ls);
const List ls1 = [1, 2, 3];
// ls1[1] = 4;
//9. 相同的const常量不会在内存中重复创建
final finalList1 = [1, 2];
final finalList2 = [1, 2];
print(identical(finalList1, finalList2)); //identical用于检查两个引用是否指向同一个对象
const constList1 = [1, 2];
const constList2 = [1, 2];
print(identical(constList1, constList2)); //identical用于检查两个引用是否指向同一个对象
//10. const 需要是编译时常量
final DateTime finalDateTime = DateTime.now();
// const DateTime constDateTime = DateTime.now();//DateTime.now() 是运行期计算出来的值
int和double是num的子类
/// ---------------------------------Numbers数值:num, int, double--------------------------------
print('-----------------------Numbers------------------------');
int i = 1; //整数值
double d = 1.0; //double 64-bit (双精度) 浮点数
int bitLength = i.bitLength;
print('bitLength: ${bitLength}'); //bitLength判断int值需要多少bit位
double maxFinite = double.maxFinite;
print('maxFinite: ${maxFinite}'); //maxFinitedouble的最大值
//int和double都是num的子类
num n1 = 1;
num n2 = 1.0;
//支持十进制、十六进制
int i1 = 0xfff;
//科学计数法
double d1 = 1.2e2; //120.0
//转换
//String->int
int i2 = int.parse('1');
double d2 = 1; //当double的值为int值时,int自动转成double
print('d2: ${d2}');
// int i2 = int.tryParse('1.0');//返回null
//int->String
String str = 123.toString(); //数字也是对象
print('-----------------------Numbers------------------------');
Dart 字符串是 UTF-16 编码的字符序列,可以使用单引号或者双引号来创建字符串
可以使用三个单引号或者双引号创建多行字符串对象
可以使用 r 前缀创建”原始raw”字符串。
可以在字符串中使用表达式: ${expression},如果表达式是一个标识符,可以省略 {},如果表达式的结果为一个对象,则 Dart 会调用对象的 toString() 函数来获取一个字符串
/// ---------------------------------Strings字符串:String--------------------------------
print('-----------------------Strings------------------------');
//Dart 字符串是 UTF-16 编码的字符序列,可以使用单引号或者双引号来创建字符串
var name = 'xiaoming';
//可以在字符串中使用表达式: ${expression},如果表达式是一个标识符,可以省略 {}。 如果表达式的结果为一个对象,则 Dart 会调用对象的 toString() 函数来获取一个字符串
var names = 'hongxue ${name}';
var rawNames = r'hongxue ${name}'; //r 前缀可以创建一个 “原始 raw” 字符串
print('names: ${names}');
print('rawNames: ${rawNames}');
//如果表达式的结果为一个对象,则 Dart 会调用对象的 toString() 函数来获取一个字符串。
// print(Map);
//可以使用三个单引号或者双引号也可以 创建多行字符串对象
var multiLinesString = '''
hongxue
xiaoming''';
print('multiLinesString: ${multiLinesString}');
//StringBuffer
var sb = StringBuffer(); //dart 2 可以省略new
sb..write('aaa')..write('bbb')..write('ccc'); //..级联符实现链式调用
sb.writeAll(['ddd', 'eee', 'fff'], ','); //第二个参数表示分隔符,将第一个参数列表里的数据用这个分隔符拼接起来
print('sb: ${sb}');
print('-----------------------Strings------------------------');
/// ---------------------------------Booleans布尔值:bool--------------------------------
print('-----------------------Booleans------------------------');
//bool :true 和false
bool isNull;
print('isNull: ${isNull}');
print('-----------------------Booleans------------------------');
/// ---------------------------------Lists列表(数组):List--------------------------------
print('-----------------------Lists------------------------');
//声明
//自动长度
List growableList = List();
// List growableList = new List()..length = 3;
growableList..add(1)..add(2)..add('xiaoming');
print('growableList: ${growableList}');
//固定长度
var list = List(3); //List的声明,可以用var也可用List。
list[0] = 1; //下标索引从0开始
list[1] = 2;
list[2] = 'xiaoming';
print('list: ${list}');
//元素类型固定
var typeList = List();
typeList.add(1);
typeList.add(2);
typeList.add(3);
print('typeList: ${typeList}');
//常用属性
int first = typeList.first;
print('typeList.first: ${first}'); //第一个元素
int last = typeList.last;
print('typeList.last: ${last}'); //最后一个元素
int length = typeList.length;
print('typeList.length: ${length}'); //元素个数
bool isEmpty = typeList.isEmpty;
print('typeList.isEmpty: ${isEmpty}'); //是否为空
bool isNotEmpty = typeList.isNotEmpty;
print('typeList.isNotEmpty: ${isNotEmpty}'); //是否不为空
Iterable reversed = typeList.reversed;
print('typeList.reversed: ${reversed}'); //倒序
//常用方法 增删改查,排序,洗牌,复制子列表
var list4 = [];
//增
list4.add(1);
print('add 1 :${list4}');
list4.addAll([2, 3, 4]);
print('addAll [2, 3, 4] :${list4}');
list4.insert(0, 0);
print('insert(0, 0) :${list4}');
list4.insertAll(1, [5, 6, 7]);
print('insertAll(1, [5, 6, 7]) :${list4}');
//删
list4.remove(5);
print('remove 5 :${list4}');
list4.removeAt(2);
print('remove at 0 :${list4}');
//改
list4[4] = 5;
print('update list4[4] to 5 :$list4}');
//range
list4.fillRange(0, 3, 9);
print('fillRange update list4[0]-list4[2] to 9 :$list4}');
Iterable getRange = list4.getRange(0, 3);
print('getRange list4[0]-list4[2] :$getRange}');
//查
var contains = list4.contains(5);
print('list4 contains 5 :${contains}');
var indexOf = list4.indexOf(1);
print('list4 indexOf 1 :${indexOf}');
int indexWhere = list4.indexWhere((test) => test == 5);
print('list4 indexWhere 5 :${indexWhere}');
//排序
list4.sort();
print('list4 sort :${list4}');
//洗牌
list4.shuffle();
print('list4 shuffle :${list4}');
//复制子列表
var list5 = list4.sublist(1);
print('sublist(1) list5 :${list5}');
//操作符
var list6 = [8, 9];
print('list6 :${list6}');
var list7 = list5 + list6;
print('list5 + list6 :${list7}');
print('-----------------------Lists------------------------');
/// ---------------------------------Maps键值对集合:Map--------------------------------
print('-----------------------Maps------------------------');
//声明
//动态类型
var dynamicMap = Map();
dynamicMap['name'] = 'hongxue';
dynamicMap[1] = 'android';
print('dynamicMap :${dynamicMap}');
//强类型
var map = Map();
map[1] = 'android';
map[2] = 'flutter';
print('map :${map}');
//也可以这样声明
var map1 = {'name': 'hongxue', 1: 'android'};
map1.addAll({'name':'xiaoming'});
print('map1 :${map1}');
//常用属性
// print(map.isEmpty); //是否为空
// print(map.isNotEmpty); //是否不为空
// print(map.length); //键值对个数
// print(map.keys); //key 集合
// print(map.values); //value集合
//常用方法 增删改查
print('-----------------------Maps------------------------');
/// ---------------------------------Sets集合:Set--------------------------------
print('-----------------------Sets------------------------');
//6. Set无重复列表
var dynamicSet = Set();
dynamicSet.add('hongxue');
dynamicSet.add('flutter');
dynamicSet.add(1);
dynamicSet.add(1);
print('dynamicSet :${dynamicSet}');
//常用属性与list类似
//常用方法 增删改查与list类似
var set1 = {'hongxue', 'flutter'};
print('set1 :${set1}');
var set2 = {'hongxue', 'xiaoming', 'dart'};
print('set2 :${set2}');
var difference12 = set1.difference(set2);
var difference21 = set2.difference(set1);
print('set1 difference set2 :${difference12}'); //返回set1集合里有但set2里没有的元素集合
print('set2 difference set1 :${difference21}'); //返回set2集合里有但set1里没有的元素集合
var intersection = set1.intersection(set2);
print('set1 set2交集 :${intersection}'); //返回set1和set2的交集
var union = set1.union(set2);
print('set1 set2并集 :${union}'); //返回set1和set2的并集
set2.retainAll(['hongxue', 'flutter']); //只保留(要保留的元素要在原set中存在)
print('set2只保留hongxue flutter :${set2}');
print('-----------------------Sets------------------------');
Main(){
Runes runes = new Runes('\u{1f605} \u6211‘);
var str1 = String.fromCharCodes(runes);
print(str1);
}
/// ---------------------------------Runes符号字符--------------------------------
//Runes用于在字符串中表示Unicode字符 https://copychar.cc/emoji/
String runesStr = '?';
print(runesStr);
print(runesStr.length); //表示占 2 个 16 位字符
print(runesStr.runes.length); //表示占 1 个 32 位字符
Runes runes = new Runes('\u{1f605} \u6211');
var str1 = String.fromCharCodes(runes); //使用String.fromCharCodes显示字符图形
print(str1);
String str2 = '\u{1f605} \u6211'; //如果非4个数值,需要把编码值放到大括号中
print(str2);
//普通函数定义
int add(int x, int y) {
return x + y;
}
print(add(1, 2));
//所有的函数都返回一个值。如果没有指定返回值,则 默认把语句 return null; 作为函数的最后一个语句执行。
testFunc() {}
;
print(testFunc());
//可省略类型(不建议)
add1(x, y) {
return x + y;
}
print(add1('1', '2'));
print(add1(1, 2));
//箭头函数:=>表达式
int add2(int x, int y) => x + y;
print('---------------------------可选参数 begin---------------------------');
//可选命名参数:使用 {param1, param2, …} 的形式来指定命名参数
int add3({int x, int y, int z}) {
x ??= 1;
y ??= 2;
z ??= 3;
return x + y + z;
}
print(add3());//打印 6
//可选位置参数:把可选参数放到 [] 中,必填参数要放在可选参数前面
int add4(int x, [int y, int z]) {
y ??= 2;
z ??= 3;
return x + y + z;
}
print(add4(1));//打印 6
//可选命名参数默认值(默认值必须是编译时常量),目前可以使用等号'='或冒号':'
//Dart SDK 1.21 之前只能用冒号,冒号的支持以后会移除,所以建议使用等号
int add5(int x, {int y = 2, int z = 3}) {
return x + y + z;
}
//前面的必填参数没有名字
print(add5(1, y: 10, z: 2));
//可选位置参数默认值(默认值必须是编译时常量),只能使用等号'='
int add6(int x, [int y = 2, int z = 3]) {
return x + y + z;
}
print(add6(1));
//使用list或map作为默认值,但必须是const
void func(
{List list = const [1, 2, 3],
Map map = const {1: 1, 'name': 'hongxue'}}) {
}
print('---------------------------可选参数 end---------------------------');
打印:
---------------------------可选参数 begin---------------------------
6
6
13
6
---------------------------可选参数 end---------------------------
print('---------------------------匿名函数 begin---------------------------');
//匿名函数
//赋值给变量
//无参匿名函数
var anonFunc1 = () => print('无参匿名函数');
anonFunc1();
//有参匿名函数
var anonFunc = (name) => 'I am $name';
print(anonFunc('xiaoming'));
//通过()调用,不推荐
// (()=>print('不推荐'))();
//匿名函数传参
List test(List list, String func(str)) {
for (var i = 0; i < list.length; i++) {
list[i] = func(list[i]);
}
return list;
}
var list = ['x', 'i', 'a', 'o', 'm'];
print(test(list, (str) => str * 2)); //String * int, Dart和Python可以这样用
//List.forEach()就用的匿名函数
List list1 = [11, 12, 13];
list1.forEach((item) => print('$item'));
print('---------------------------匿名函数 end---------------------------');
打印如下:
---------------------------匿名函数 begin---------------------------
无参匿名函数
I am xiaoming
[xx, ii, aa, oo, mm]
11
12
13
---------------------------匿名函数 end---------------------------
//返回Function对象(闭包)
Function makeAddFunc(int x) {
x++;
return (int y) => x + y;
}
var addFunc = makeAddFunc(2);
print(addFunc(3));
打印:6
//函数别名
typedef MyFunc(int a, int b);
//根据MyFunc相同的函数签名定义两个函数
subtsract(int a, int b) {
print('subtsract: ${a - b}');
}
divide(int a, int b) {
print('divide: ${a / b}');
}
//typedef 也可以作为参数传递给函数
calculator(int a, int b, MyFunc func) {
func(a, b);
}
void main(){
// 函数别名
MyFunc myFunc;
//可以指向任何同签名的函数
myFunc = subtsract;
myFunc(5, 2);
myFunc = divide;
myFunc(8, 2);
//typedef 作为参数传递给函数
calculator(5, 2, subtsract);
calculator(8, 2, divide);
}
打印:
subtsract: 3
divide: 4.0
subtsract: 3
divide: 4.0
main() {
//Operators 操作符
/// ---------------------------------后缀操作符 ?.--------------------------------
// 条件成员访问 和 . 类似,但是左边的操作对象不能为 null,例如 foo?.bar 如果 foo 为 null 则返回 null,否则返回 bar 成员
String a;
print(a?.length);
/// ---------------------------------取商操作符 ~/--------------------------------
// 被除数 ÷ 除数 = 商 ... 余数,A ~/ B = C,这个C就是商。相当于Java里的 /
print(2 / 3);
print(2 ~/ 3);
/// ---------------------------------类型判定操作符--------------------------------
//类型判定操作符:as、is、is!在运行时判定对象类型
//as 类型转换
num iNum = 1;
num dNum = 1.0;
int i = iNum as int;
double d = dNum as double;
print([i, d]);
// String s = iNum as String;
//is 如果对象是指定的类型返回 True
print(iNum is int);
Child child;
Child child1 = new Child();
print(child is Parent); //child is Null
print(child1 is Parent);
//is! 如果对象是指定的类型返回 False
print(iNum is! int);
/// ---------------------------------条件表达式--------------------------------
// 三目运算符 condition ? expr1 : expr2
bool isFinish = true;
String txtVal = isFinish ? 'yes' : 'no';
// expr1 ?? expr2,如果 expr1 是 non-null,返回其值; 否则执行 expr2 并返回其结果。
bool isPaused;
isPaused = isPaused ?? false;
//或者
isPaused ??= false;
/// ---------------------------------级联操作符--------------------------------
// .. 可以在同一个对象上 连续调用多个函数以及访问成员变量。
// 严格来说, 两个点的级联语法不是一个操作符。 只是一个 Dart 特殊语法。
StringBuffer sb = new StringBuffer();
sb
..write('hongxue')
..write('flutter')
..write('\n')
..writeln('xiaoming');
//重写操作符
}
class Parent {}
class Child extends Parent {}
打印:
null
0.6666666666666666
0
[1, 1.0]
true
false
true
false
重载操作符:
void main(){
final v1 = Vector(5,6);
final v2 = Vector(2,2);
final r1 = v1 + v2;
final r2 = v1 - v2;
print([r1.x,r1.y]);
print([r2.x,r2.y]);
}
//重载操作符
class Vector{
final int x;
final int y;
const Vector(this.x,this.y);
//重载+
Vector operator +(Vector v){
return new Vector(x + v.x, y + v.y);
}
//重载
Vector operator -(Vector v){
return new Vector(x - v.x, y - v.y);
}
}
打印:
[7, 8]
[3, 4]
main() {
var collection = [0, 1, 2];
//forEach
collection.forEach((item) => print('forEach: $item'));
//for-in遍历元素
for (var item in collection) {
print('for-in: $item');
}
}
打印:
forEach: 0
forEach: 1
forEach: 2
for-in: 0
for-in: 1
for-in: 2
// 抛出Exception 对象
// throw new FormatException(‘格式异常');
// 抛出Error 对象
// throw new OutOfMemoryError();
// 抛出任意非null对象
// throw '这是一个异常';
try {
throw new OutOfMemoryError();
} on OutOfMemoryError {
print('没有内存了');
} on Error catch(e) {
print('Unknown error: $e');
} catch (e, s) {
print('Exception details: $e');
print('Stack Trace: $s');
} finally {
print('end');
}
打印:
没有内存了
end
//java中写法
class Point {
double x;
double y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
//dart建议写法
class Point {
num x;
num y;
Point(this.x, this.y);
}
main() {
//普通构造函数
var p = new Point(1, 1); //new 可省略 var point = Point(1, 2);
print(p);
}
打印:
Point(x = 1, y = 1)
class Point {
num x;
num y;
Point(this.x, this.y);
//命名构造函数
Point.fromJson(Map json) {
x = json['x'];
y = json['y'];
}
}
void main(){
//命名构造函数
p = Point.fromJson({'x': 2, 'y': 2});
print(p);
}
打印:
Point(x = 2, y = 2)
class Point {
num x;
num y;
Point(this.x, this.y);
//重定向构造函数,使用冒号调用其他构造函数
Point.alongXAxis(num x) : this(x, 0);
}
//重定向构造函数
p = Point.alongXAxis(0);
print(p);
打印:
Point(x = 0, y = 0)
import 'dart:math';
class Point {
//final变量不能被修改,必须被构造函数初始化
final num x;
final num y;
final num distanceFromOrigin;
//初始化列表
Point(x, y)
: x = x,
y = y,
distanceFromOrigin = sqrt(x * x + y * y);
}
class Parent {
int x;
int y;
//父类命名构造函数不会传递
Parent.fromJson(x, y)
: x = x,
y = y {
print('父类命名构造函数');
}
}
class Child extends Parent {
int x;
int y;
//若超类没有默认构造函数, 需要手动调用超类其他构造函数
Child(x, y) : super.fromJson(x, y) {
//调用父类构造函数的参数无法访问 this
print('子类构造函数');
}
//在构造函数的初始化列表中使用super(),需要把它放到最后
Child.fromJson(x, y)
: x = x,
y = y,
super.fromJson(x, y) {
print('子类命名构造函数');
}
}
main() {
//调用超类构造函数
var child = Child.fromJson(1, 2);
var child1 = Child(3, 4);
}
打印:
超类命名构造函数
子类命名构造函数
超类命名构造函数
子类构造函数
class Point2 {
//定义const构造函数要确保所有实例变量都是final
final num x;
final num y;
static final Point2 origin = const Point2(0, 0);
//const关键字放在构造函数名称之前,且不能有函数体
const Point2(this.x, this.y);
}
void main(){
//常量构造函数
var p2 = const Point2(4, 4);
print(p2);
var p21 = Point2(4, 4); //创建的是非 常量对象
var p22 = const Point2(4, 4);
print(identical(p2, p21));
print(identical(p2, p22));
}
打印:
Point2(x = 4, y = 4)
false
true
class Singleton {
String name;
//工厂构造函数无法访问this,所以这里要用static
static Singleton _cache;
//工厂方法构造函数,关键字factory
factory Singleton([String name = 'singleton']) =>
Singleton._cache ??= Singleton._newObject(name);
//定义一个命名构造函数用来生产实例
Singleton._newObject(this.name);
}
打印:true
main() {
//set get
var rect = new Rectangle(1, 1, 10, 10);
print(rect.left);
rect.right = 15;
print(rect.left);
}
//setter getter
//每个实例变量都隐含的具有一个 getter, 如果变量不是 final 的则还有一个 setter
//可以通过实行 getter 和 setter 来创建新的属性, 使用 get 和 set 关键字定义 getter 和 setter
class Rectangle {
num left;
num top;
num width;
num height;
Rectangle(this.left, this.top, this.width, this.height);
// getter 和 setter 的好处是,可以开始使用实例变量,后面可以把实例变量用函数包裹起来,而调用你代码的地方不需要修改。
//获取right值
num get right => left + width;
//设置right值,同时left也发生变化
set right(num value) => left = value - width;
//获取bottom值
num get bottom => top + height;
//设置bottom值,同时top也发生变化
set bottom(num value) => top = value - height;
}
打印:
1
5
工厂模式两种方式:
1 创建工厂构造函数
main() {
//创建工厂构造函数
var footMassage = new Massage('foot');
footMassage.doMassage();
var bodyMassage = new Massage('body');
bodyMassage.doMassage();
var specialMassage = new Massage('%#@##@##');
specialMassage.doMassage();
}
//工厂模式
abstract class Massage {
factory Massage(String type) {
switch (type) {
case 'foot':
return new FootMassage();
case 'body':
return new BodyMassage();
default:
return new SpecialMassage();
}
}
void doMassage();
}
class FootMassage implements Massage {
@override
doMassage() {
print('脚底');
}
}
class BodyMassage implements Massage {
@override
void doMassage() {
print('全身');
}
}
class SpecialMassage implements Massage {
@override
void doMassage() {
print('特殊');
}
}
打印:
脚底
全身
特殊
2 创建顶级函数
main() {
//创建顶级函数
var footMassage = massageFactory('foot');
footMassage.doMassage();
var bodyMassage = massageFactory('body');
bodyMassage.doMassage();
var specialMassage = massageFactory('xxx');
specialMassage.doMassage();
}
//工厂函数
class Massage {
void doMassage(){
print('按摩');
}
}
class FootMassage extends Massage {
@override
doMassage() {
print('脚底');
}
}
class BodyMassage extends Massage {
@override
void doMassage() {
print('全身');
}
}
class SpecialMassage extends Massage {
@override
void doMassage() {
print('特殊');
}
}
Massage massageFactory(String type){
switch (type) {
case 'foot':
return new FootMassage();
case 'body':
return new BodyMassage();
default:
return new SpecialMassage();
}
}
打印:
脚底
全身
特殊
main() {
//可调用类
var cf = new ClassFunction();
var out = cf("hongxue","flutter,","xiaoming");
print('$out'); // Hi there, gang!
print(cf.runtimeType); // WannabeFunction
print(out.runtimeType); // String
print(cf is Function); // true
}
//可调用类
class ClassFunction {
call(String a, String b, String c) => '$a $b $c!';
}
打印:
hongxue flutter, xiaoming!
ClassFunction
String
false
main() {
Bicycle().transport();
Motorcycle().transport();
Car().transport();
WoodenCar().transport(); //四轮木制脚踏车
}
//交通工具类,拥有运输功能
abstract class Transportation {
//运输功能
void transport();
}
//自行车
class Bicycle extends Transportation
with TwoWheelTransportation, LowSafetyIndex, BodyEnergyTransportation {
@override
void transport() {
print(
"自行车:\n动力组件: ${powerUnit()} , 安全指数: ${safetyIndex()} , 动力来源:${energy()}");
}
// String safetyIndex() => "low";
//
// String powerUnit() => "两个轮子";
//
// String energy() => "全靠腿登";
}
//摩托车
class Motorcycle extends Transportation
with TwoWheelTransportation, LowSafetyIndex, GasolineEnergyTransportation {
@override
void transport() {
print(
"摩托车:\n动力组件: ${powerUnit()} , 安全指数: ${safetyIndex()} , 动力来源:${energy()}");
}
// String safetyIndex() => "low";
//
// String powerUnit() => "两个轮子";
//
// String energy() => "汽油";
}
//汽车
class Car extends Transportation
with
FourWheelTransportation,
MiddleSafetyIndex,
GasolineEnergyTransportation {
@override
void transport() {
print(
"汽车:\n动力组件: ${powerUnit()} , 安全指数: ${safetyIndex()} , 动力来源:${energy()}");
}
// String safetyIndex() => "middle";
//
// String powerUnit() => "四个轮子";
//
// String energy() => "汽油";
}
//双轮交通工具
class TwoWheelTransportation {
String powerUnit() => "两个轮子";
}
//四轮交通工具,一般来说安全性能为中
class FourWheelTransportation {
String powerUnit() => "四个轮子";
}
//安全指数中等的交通工具儿
class MiddleSafetyIndex {
String safetyIndex() => "middle";
}
//安全指数低的交通工具儿
class LowSafetyIndex {
String safetyIndex() => "low";
}
//人力发动机
class BodyEnergyTransportation {
String energy() => "全靠腿登";
}
//汽油能源交通工具
class GasolineEnergyTransportation {
String energy() => "汽油";
}
//四轮木制脚踏车
class WoodenCar extends Car
// with LowSafetyIndex, BodyEnergyTransportation
//implements LowSafetyIndex, BodyEnergyTransportation
{
@override
void transport() {
print(
"四轮木制脚踏车:\n动力组件: ${powerUnit()} , 安全指数: ${safetyIndex()} , 动力来源:${energy()}");
}
}
打印:
自行车:
动力组件: 两个轮子 , 安全指数: low , 动力来源:全靠腿登
摩托车:
动力组件: 两个轮子 , 安全指数: low , 动力来源:汽油
汽车:
动力组件: 四个轮子 , 安全指数: middle , 动力来源:汽油
四轮木制脚踏车:
动力组件: 四个轮子 , 安全指数: middle , 动力来源:汽油
顺序问题:
void main(){
var messageAB = AB().getMessage();
print(messageAB);
var messageBA = BA().getMessage();
print(messageBA);
var messageC = C().getMessage();
print(messageC);
var messageCC = CC().getMessage();
print(messageCC);
}
//顺序问题
//如果2个或多个超类拥有相同签名的A方法,那么子类会以继承的最后一个超类中的A方法为准。
//当然这是子类没有重写A方法的前提下,如果子类自己重写了A方法则以本身的A方法为准
class A {
String getMessage() => 'A';
}
class B {
String getMessage() => 'B';
}
class P {
String getMessage() => 'P';
}
class AB extends P with A, B {}
class BA extends P with B, A {}
class C extends P with B, A {
String getMessage() => 'C'; //优先级最高的是在具体类中的方法。
}
class CC extends P with B implements A {
} //这里的implement只是表明要实现A的方法,这个时候具体实现是再B中mixin了具体实现
打印:
B
A
C
B
void main(){
//使用泛型,很多的容器对象,在创建对象时都可以定义泛型类型,跟java一样
var list = List();
list.add('aaa');
list.add('bbb');
list.add('ccc');
print(list);
var map = Map();
map[1] = 'aaaa';
map[2] = 'bbbb';
map[3] = 'cccc';
print(map);
}
打印:
[aaa, bbb, ccc]
{1: aaaa, 2: bbbb, 3: cccc}
void main(){
var key = addCache('hongxue', 'xiaoming');
print(key);
}
//泛型函数
K addCache(K key, V value) {
K temp = key;
print('${key}: ${value}');
return temp;
}
打印:
hongxue: xiaoming
hongxue
void main(){
//构造函数泛型
var p = Phone('123456');
print(p.mobileNumber);
}
//构造函数泛型
class Phone {
final T mobileNumber;
Phone(this.mobileNumber);
}
打印:
123456
void main(){
//泛型限制, 通过 extends 关键字限定可泛型使用的类型
var footMassage = FootMassage();
var m = Massage(footMassage);
m.massage.doMassage();
}
//泛型限制
class Massage {
final T massage;
Massage(this.massage);
}
class FootMassage {
void doMassage() {
print('脚底');
}
}
打印:
脚底
void main(){
var names = List();
print(names is List);//true
print(names.runtimeType); // List
}
打印:
true
List
使用import关键字来载入库:
import "dart:math";
void main() {
print(sqrt(4));//开平方 2.0
}
https://pub.flutter-io.cn/
1.编写pubspec.yaml:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.0
dio: ^2.1.0
2.调用
import "package:dio/dio.dart";
void main() {
getHttp();
}
void getHttp() async {
try {
Response response = await Dio().get("https://www.baidu.com");
print(response);
} catch (e) {
print(e);
}
}
新建一个mylib1.dart
class MyLib {
String name;
static MyLib _cache; //工厂构造函数无法访问 this。所以这里要静态的
factory MyLib([String name = 'singleton']) =>
MyLib._cache ??= MyLib._newObject(name);
//定义一个命名构造函数用来生产实例
MyLib._newObject(this.name);
}
class Test {
void test() => print('Test');
}
test(){
}
//载入文件
import “mylib1.dart";
void main() {
var myLib1 = MyLib();
}
如果两个库有冲突的标识符,可以为其中一个或两个库都指定前缀:
mylib1.dart
class MyLib {
String name;
static MyLib _cache; //工厂构造函数无法访问 this。所以这里要静态的
factory MyLib([String name = 'singleton']) =>
MyLib._cache ??= MyLib._newObject(name);
//定义一个命名构造函数用来生产实例
MyLib._newObject(this.name);
}
class Test {
void test() => print('Test');
}
test(){
}
mylib2.dart
class MyLib{
String name;
static MyLib _cache; //工厂构造函数无法访问 this。所以这里要静态的
factory MyLib([String name = 'singleton']) =>
MyLib._cache ??= MyLib._newObject(name);
//定义一个命名构造函数用来生产实例
MyLib._newObject(this.name);
}
class Test{
void test() => print('Test');
}
载入文件
import 'mylib1.dart' as lib1; //载入文件
import 'mylib2.dart' as lib2; //如果两个库有冲突的标识符,可以为其中一个或两个库都指定前缀
void main() {
var myLib = lib1.MyLib();
var myLib2 = lib2.MyLib();
}
import 'mylib1.dart' as lib1 show Test; //只载入库的某些部分
import 'mylib2.dart' as lib2 hide Test; //筛选掉库的某些部分
void main(){
//选择性载入
var test = lib1.Test();
var lib = lib2.MyLib();
}
import 'mylib1.dart' deferred as lazyLib; //延迟载入
void main(){
//延迟载入
lazyLoad();
}
//延迟载入
//可提高程序启动速度
//用在不常使用的功能
//用在载入时间过长的包
lazyLoad() async {
await lazyLib.loadLibrary();
var t = lazyLib.Test();
t.test();
}
新建util.dart
part of mylib;
void printUtil() => print('util');
新建tool.dart
part of mylib;
void printTool() => print('tool');
新建mylib.dart
library mylib;
part 'util.dart';
part 'tool.dart';
void printMyLib() => print('mylib');
import 'mylib/mylib.dart';//载入自定义库
void main(){
//载入自定义库
printMyLib();
printUtil();
printTool();
}
打印:
mylib
util
tool
import 'dart:async';
main() async {
// async wait
getName1();
getName2();
getName3();
}
// async wait
Future getName1() async {
// getStr1();//可以不用await打断点看下await后的区别
await getStr1(); //遇到第一个await表达式执行暂停,返回future对象,await表达式执行完成后继续执行
await getStr2(); //await表达式可以使用多次
print('getName1');
}
getStr1() {
print('getStr1');
}
getStr2() {
print('getStr2');
}
getName2() {
print('getName2');
}
getName3() {
print('getName3');
}
打印:
getStr1
getName2
getName3
getStr2
getName1
import 'dart:async';
main() async {
//then catchError whenComplete
new Future(() => futureTask()) // 异步任务的函数
.then((m) => "a:$m") // 任务执行完后的子任务
.then((m) => print('a$m')) // 其中m为上个任务执行完后的返回的结果
.then((_) => new Future.error('error'))
.then((m) => print('damon'))
.whenComplete(() => print('whenComplete1')) //不是最后执行whenComplete,通常放到最后回调
// .catchError((e) => print(e))//如果不写test默认实现一个返回true的test方法
.catchError((e) => print('catchError:' + e), test: (Object o) {
print('test:' + o);
return true; //返回true,会被catchError捕获
// return false; //返回false,继续抛出错误,会被下一个catchError捕获
})
.catchError((e) => print('catchError2:' + e))
// .then((m) => print('dongnao'))
// .whenComplete(() => print('finish'))
;
}
int futureTask() {
// throw 'error';
return 10;
}
打印:
aa:10
whenComplete1
test:error
catchError:error
import 'dart:async';
main() async {
// Future
testFuture();
}
//Future
void testFuture() {
Future f = new Future(() => print("f1"));
Future f1 = new Future(() => null); //7163524
// Future f1 = new Future.delayed(Duration(seconds: 1) ,() => null);//7132465
Future f2 = new Future(() => null);
Future f3 = new Future(() => null);
f3.then((_) => print("f2"));
f2.then((_) {
print("f3");
new Future(() => print("f4"));
f1.then((_) {
print("f5");
});
});
f1.then((m) {
print("f6");
});
print("f7");
}
打印:
f7
f1
f6
f3
f5
f2
f4
import 'dart:async';
main() async {
//scheduleMicrotask
testScheduleMicrotask();
}
//scheduleMicrotask
void testScheduleMicrotask() {
//918346572
scheduleMicrotask(() => print('s1'));
new Future.delayed(new Duration(seconds: 1), () => print('s2'));
new Future(() => print('s3')).then((_) {
print('s4');
scheduleMicrotask(() => print('s5'));
}).then((_) => print('s6'));
new Future(() => print('s10'))
.then((_) => new Future(() => print('s11')))
.then((_) => print('s12'));
new Future(() => print('s7'));
scheduleMicrotask(() => print('s8'));
print('s9');
}
打印:
s9
s1
s8
s3
s4
s6
s5
s10
s7
s11
s12
s2
void main(){
//同步生成器
//调用getSyncGenerator立即返回Iterable
var it = getSyncGenerator(5).iterator;
// 调用moveNext方法时getSyncGenerator才开始执行
while (it.moveNext()) {
print(it.current);
}
}
//同步生成器: 使用sync*,返回的是Iterable对象
Iterable getSyncGenerator(int n) sync* {
print('start');
int k = n;
while (k > 0) {
//yield会返回moveNext为true,并等待 moveNext 指令
yield k--;
}
print('end');
}
打印:
start
5
4
3
2
1
end
1:
void main(){
//异步生成器
//调用getAsyncGenerator立即返回Stream,只有执行了listen,函数才会开始执行
//getAsyncGenerator(5).listen((value) => print(value));
StreamSubscription subscription = getAsyncGenerator(5).listen(null);
subscription.onData((value) {
print(value);
});
}
//异步生成器: 使用async*,返回的是Stream对象
Stream getAsyncGenerator(int n) async* {
print('start');
int k = 0;
while (k < n) {
//yield不用暂停,数据以流的方式一次性推送,通过StreamSubscription进行控制
yield k++;
}
print('end');
}
打印:
start
0
1
2
3
4
end
2 :
import 'dart:async';
void main(){
//异步生成器
//调用getAsyncGenerator立即返回Stream,只有执行了listen,函数才会开始执行
StreamSubscription subscription = getAsyncGenerator(5).listen(null);
subscription.onData((value) {
print(value);
if (value >= 2) {
subscription.pause(); //可以使用StreamSubscription对象对数据流进行控制
}
});
}
//异步生成器: 使用async*,返回的是Stream对象
Stream getAsyncGenerator(int n) async* {
print('start');
int k = 0;
while (k < n) {
//yield不用暂停,数据以流的方式一次性推送,通过StreamSubscription进行控制
yield k++;
}
print('end');
}
打印:
start
0
1
2
import 'dart:async';
void main(){
//递归生成器
//同步
var it1 = getSyncRecursiveGenerator(5).iterator;
while (it1.moveNext()) {
print(it1.current);
}
//异步
getAsyncRecursiveGenerator(5).listen((value) => print(value));
}
//递归生成器:使用yield*
Iterable getSyncRecursiveGenerator(int n) sync* {
if (n > 0) {
yield n;
yield* getSyncRecursiveGenerator(n - 1);
}
}
//异步递归生成器
Stream getAsyncRecursiveGenerator(int n) async* {
if (n > 0) {
yield n;
yield* getAsyncRecursiveGenerator(n - 1);
}
}
main() {
dynamic tv = new Television();
tv.activate();
tv.turnOn();
}
class Television {
@deprecated
void activate() {
turnOn();
}
void turnOn() {
print('Television turn on!');
}
}
main() {
dynamic tv = new Television();
tv.activate();
tv.turnOn();
tv.turnOff();
}
class Television {
@deprecated
void activate() {
turnOn();
}
void turnOn() {
print('Television turn on!');
}
@override
noSuchMethod(Invocation mirror) {
print('没有找到方法');
}
}
//todo.dart
class Todo {
final String who;
final String what;
const Todo({this.who, this.what});
}
import 'todo.dart’;
main() {
dynamic tv = new Television();
tv.doSomething();
}
class Television {
@Todo(who: 'damon', what: 'create a new method')
void doSomething() {
print('doSomething');
}
}
单行注释以//开头。Dart编译器会忽略//和行尾之间的所有内容。
// 这是单行注释
/*
* 这是多行注释
* 这是多行注释
*/
/// 这是文档注释
/**
* 这是文档注释
*/