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
31
32
33
34
35
36
37
38
39
40
41
42
43
 /*
未初始化变量声明
dynamic、var、Object

数据类型
int / double / String / bool / List / Maps
*/
var name = 'doreen' // 再次赋值的时候类型需要一致
String name = 'sherry'

// 模板字符串 也可以是 """ ... """
String str = '''
hello,
thank you
'''
print( name +" "+ str )
// => print("$name $str")

int age = 13
bool flag = true / false (只能是这两个值)
var arr = ['aa'] // => var arr = new List() arr.add('aa')
// new List(<string>) 指定list的类型

// Maps类型和Object类似
var person = {
"name":"doreen",
"age":20
}
print(person['age']) // 不能通过person.age

var person = new Map() // new 可以省略
person["name"] = "sherry"

// const 定义之后不能被修改的变量
const PI = 3.14159

// final 基本与const一致
final PI = 3.14159

// 区别: final是惰性初始化,使用的时候才会被赋值 (需要通过方法 赋值给常量的时候只能用final)
final a = new DateTime.now() // √
const a = new DateTime.now() // ×

类型判断

is 关键词判断

1
if(str is String){ ... }

List常用属性和方法

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
属性:
.length 长度
.reversed 翻转(返回的字符串)
.isEmpty 是否为空
.isNotEmpty 是否不为空

方法:
.add() 增加一个
.addAll([]) 增加多个
.indexOf() 查找 传入具体值
.remove() 删除 传入具体值
.removeAt() 删除 传入具体索引
.fillRange(start,end,value) 修改(替换)
.insert(index,value) 指定位置插入
.insertAll(index,list) 指定位置插入List
.toList() 其他类型转换成List
.join() List转换成字符串
.split() 字符串转换成List
.forEach() 遍历
.map()
.where() 筛选符合条件的集合
.any() 有一个满足条件返回true
.every() 所有满足条件 返回true

myList.forEach((value){
print(value)
})
myList.map((value){
return value*2
})
myList.map((value){
return value>2
})
myList.any((value){
return value>2
})

Maps常用属性和方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
属性:
.keys 获取所有key值
.values 获取所有value值
.isEmpty
.isNotEmpty

方法:
.remove(key) 删除指定key的数据
.addAll({...}) 合并映射 给映射内增加属性
.containsValue() 查看映射内的值 返回true/false
.forEach()
.map()
.where()
.any()
.every()

流程控制语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if(age>=18){
print('成年人');
}else{
print('未成年人');
}


for(var item in flyObject){
print(item);
}


for(int i=0;i<10;i++){
print(i);
}

while(i>10){
i-=1;
}

// switch case ,break,continue

函数

返回类型 方法名称 (参数,…){ 方法体 return 返回值; }

1
2
3
4
5
6
7
8
9
int fibonacci( int n ){
if( n==0 || n==1 ) return n;
return fibonacci(n-1) - fibonacci(n-2)
// 返回值类型为 数字
}

void fun(){
// 没有返回值 / 不指定返回值类型
}

可选参数

1
2
3
4
5
6
7
8
// 可选参数用 [] 表示,默认参数直接用赋值语句
String printUserInfo(String username,[String sex='女',int age]){
if(age!=null){
return '$username ----- $age ----- $sex';
}else{
return '$username';
}
}

可选命名参数

1
2
3
4
5
6
7
8
9
10
11

// 命名参数用 {} 表示,默认参数直接用赋值语句
String printUserInfo(String username,{ int age,String sex='女' }){
if(age!=null){
return '$username ----- $age ----- $sex';
}else{
return '$username';
}
}
// 通过 key: value 的方式填写参数
printUserInfo('doreen',age:20)

如果是List或者Map作为默认参数,赋值必须要用const
void add({List list = const [1,2,3] })

匿名函数

无参匿名

var fun = () => print(‘aaa’);

有参匿名

var fun = (String name) => print(name);

导入

通过import关键字来访问其他库中的内容

1
import 'demo.dart'

类(Class)

构造函数可以写多个
默认构造函数—实例化的时候调用 (一个)
命名构造函数—通过类调用 (多个)

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
45
46
47
48
49
50
/*
如果想要写成私有属性/方法
就需要把类单独抽离成一个文件 引入使用
并且在定义属性/方法的时候在名字前面加上 _
eg:
String _name;
void _getName(){}
*/
class People {
String name;
int age;

void getInfo(){
// print('$name---$age') =>
print('${this.name}---${this.age}')
}

void setInfo(int age) {
this.age = age;
}

// 默认构造函数,带有可以直接为成员变量赋值的语法糖
People(this.name,this.age)
/*
=>
People(name, age) {
this.name = name;
this.age = age;
}

// 赋默认值
People():name='doreen',age=10{}
*/

// 命名构造函数
People.now(){
print('我是命名构造函数')
}

}

void main(){
var p = new People('doreen', 24);
// People p = new People('jerry',9)

p.getInfo(); // doreen---24
p.setInfo(18);
p.getInfo(); // doreen---18
People.now(); // 我是命名构造函数
}

getter

直接通过访问属性的方式访问方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Rect {
num height;
num width;
Rect(this.height,this.width);

// 类似于计算属性
get area {
return this.height*this.width;
}

getArea(){
return this.height*this.width;
}
}

void main() {
Rect r = new Rect(10,9)
print('面积:${r.area}'); //get
print('面积:${r.getArea()}'); //方法
}

setter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 class Rect {
num height;
num width;
Rect(this.height,this.width);

set areaHeight(value) {
this.height = value;
}

setHeight(value){
this.height = value;
}
}

void main() {
Rect r = new Rect(10,9)

r.areaHeight = 5;
print(r.height); // 5
r.setHeight(9);
print(r.height); // 9
}

static 静态成员

使用static关键字来实现类级别的变量和函数
静态方法不能访问非静态成员,非静态方法可以访问静态成员
实例化对象不能访问、只能通过类直接访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class People {
String name = 'doreen';
static int age = 10;
static void show() {
print(age); // 访问静态属性
// print(this.name); × 不能访问非静态属性
}
void printInfo() {
show(); // 不需要this
}
}

void main() {
var p = new People();
// p.show(); ×
print(People.age); // 10
People.show(); // 10
}

对象的操作符

? 条件运算符
as 类型转换
is 类型判断
.. 级联操作
?? 是否为空

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
People p;
p?.printInfo(); // 如果p为空就不执行

var p1;
p1 = '';
p1 = new Person();
(p1 as Person).printInfo();

print( p is People) // 判断对象是否属于xx类

var p = new Person()
p..name='doreen' // 直接换行不需要分号
..age=9
..printInfo();

/*
=>
p.name = 'doreen';
p.age = 9;
p.printInfo();
*/

bool flag;
flag ??= false; // flag为空则赋值false否则给原本值

继承

子类使用extends关键词来继承父类
子类会继承父类里面可见的属性和方法 但不会继承构造函数
子类能复写父类的方法 getter和setter

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
class Person {
String name='doreen';
num age=8;
void printInfo(){
print('${this.name}----${this.age}')
}
Person(this.name,this.age)
}

class Women extends Person {
String sex;
// 实例化属性时 赋值给父类
Women(String name, num age,this.sex) : super(name, age);

// override表示重写父类方法 建议写上
@override
void printInfo() {
// super.printInfo(); // print('${this.name}----${this.age}')
print('${this.name}--${this.sex}--${this.age}');
}

// 字类方法调用父类方法
void run(){
super.printInfo();
print('hhh')
}

}

抽象类

dart抽象类主要用于定义标准,字类可以继承抽象类,也可以实现抽象类接口

  1. 抽象类通过abstract关键字来定义
  2. dart中的抽象方法不能用abstract声明,dart中没有实体方法我们称为抽象方法
  3. 如果子类继承抽象类必须得实现里面的抽象方法
  4. 如果把抽象类当作接口实现的话必须得实现抽象类里面定义的所有属性和方法
  5. 抽象类不能被实例化,只有继承它的子类

extends抽象类和implements的区别:

  • 如果要复用抽象类型里面的方法,并且要用抽象方法约束子类的话我们就用extends继承抽象类
  • 如果只是把抽象类当作标准的话我们就用implements实现抽象类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
abstract class Person {
eat(); // 父类定义抽象方法

// 公共(普通)方法
void printInfo(){
print('抽象类的普通方法')
}
}

class Women extends Person {
// 子类必须继承抽象方法,并实现
@override
eat() {
print('handle eat');
}
}

void main() {
// var a = new Person() × 抽象类无法直接被实例化
var doreen = new Women();
doreen.eat();
}

多态

允许将子类类型的指针赋值给父类类型的指针,同一个函数调用会有不同的执行效果
子类的实例赋值给父类的引用
多态就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现

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
abstract class Person {
eat(); // 抽象方法
}

class Women extends Person {
@override
eat() {
print('women eat');
}

run() {
print('run');
}
}

class Men extends Person {
@override
eat() {
print('men eat');
}
}

void main() {
Person doreen = new Women(); // 子类的实例赋值给父类的引用
Person jerry = new Men();
doreen.eat();
// doreen.run(); ×
jerry.eat();
}

接口

dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现,同样使用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
27
28
29
30
31
32
33
34
35
36
37
38
abstract class Db {
// 当作接口(约定、规范)
String uri;
add(String data);
delete();
}

// 父类型里面定义的子类必须按照父类的规范去实现
// 子类可以自己扩展属性或方法
class MySQL implements Db {
@override
String uri;

@override
add(String data) {
print('MySQL的add方法' + data);
}

@override
delete() {
print('MySQL的delete方法');
}
}

class Mongodb implements Db {
@override
String uri;

@override
add(String data) {
print('mongodb的add方法' + data);
}

@override
delete() {
print('mongodb的delete方法');
}
}

多个接口的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
abstract class A {
printA();
}

abstract class B {
printB();
}

// 获取A,B类的全部属性和方法
class C implements A, B {
@override
printA() {
print('A接口');
}

@override
printB() {
print('B接口');
}
}

mixins

mixins的使用条件:

  1. 作为mixins的类只能继承自Object,不能继承其他类
  2. 作为mixins的类不能有构造函数
  3. 一个类可以mixins多个mixins类
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
// class C extends A,B {}  × 可以获取多个接口但是不能实现多继承

// class A extends Aa {} × 作为mixins的类只能继承自Object,不能继承其他类
class A {
String name='a';
// A(this.name) × 作为mixins的类不能有构造函数
void printA() {
print('A');
}
}

class B {
void printB() {
print('B');
}
}

// 通过with取代extends 相当于继承了A和B
// A和B的顺序 后者会覆盖前者的同样的属性和方法
class C with A, B {}

// Person内可以有构造函数,并继承了三者的属性和方法
class C extends Person with A,B {}

void main() {
C c = new C();
c.printA();
c.printB();
}

泛型

解决类、接口、方法的复用性、以及不特定数据类型的支持(类型校验)

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
// T可以用任意字母代替 ,表示泛型(任意类型)
// T---① getData<T>(T----② value)
// ① 对返回的参数进行校验
// ② 对传入的参数进行校验

T getData<T>(T value) {
return value;
}
void main(){
// 在<>内指定参数类型
getData<String>('hello');
// getData<String>(123); ×

}

// 在类中使用泛型
class A<T>{
...
}
new A<String>()


// 在接口中使用泛型
abstract class Cache<T> {
getByKey(String key);
void setByKey(String key, T value);
}

// =>
abstract class ObjectCache {
getByKey(String key);
void setByKey(String key, Object value);
}
abstract class StringCache {
getByKey(String key);
void setByKey(String key, String value);
}

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2019-2023 John Doe
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信