函数相关
dart当中函数也是一个对象,具备共同的抽象类Function
因为是抽象类,所以不能直接用其执行new创建对象
可选参数
dart在定义函数的时候可以在形参表的末尾添加可选参数
有命名参数和匿名参数两种形式
1 | void main() { |
命名的可选参数因为传参时指定形参名称,所以就不会强制顺序的匹配了
可选参数的声明必须在形参表的末尾
匿名函数和箭头函数
匿名函数
1 | (参数1, 参数2 ...) { |
匿名函数不能声明返回值类型,或者说它的返回值是任意类型的,相当于是dynamic
dynamic并不算一种类型,只是作为一个关键字表示动态类型
就像var也是关键字,但是会执行类型推导
箭头函数
1 | (参数1, 参数2 ...) => 返回值 |
箭头函数只能有一个表达式作为返回值,而不能有其他语句
函数对象都可以使用变量进行接收
级联调用
dart当中使用..
来实现级联调用
1 | List list1 = [10,15,20]; |
面向对象
使用class
关键字来声明一个类,创建对象时new
关键字可以省略
dart中不支持函数重载
可以使用.
来访问对象的成员
当然如果变量是null会报空指针的错误
可以判断是否为null
也可以使用?.
操作符,相当于自带判断是否为null,如果是null就不执行调用
类如果实现了call
函数,那么它的实例就可以直接当做函数来执行调用
1 | void main() { |
计算属性
对于不是固定值,而是需要使用一些逻辑获得计算结果的情况
我们可以将其定义为类当中的一个函数,也可以使用计算属性
计算属性分为get
和set
两种
1 | void main() { |
它本身当然是个函数,也可以使用箭头函数的写法
构造函数
定义一个类时,如果不写构造函数,会默认提供一个无参的构造函数
支持匿名构造函数与命名构造函数两种
构造函数也不能被重载,如果要实现一个类有多个构造函数,就必须使用命名构造函数
1 | class Person { |
命名构造函数调用时写作 new Person.withName(‘sookie’)
对于final
修饰的类属性,想要在构造函数进行初始化,只能使用这种语法糖的形式来写
1 | class Person { |
常量对象
1 | void main() { |
工厂构造方法
dart自带了工厂设计模式的实现,工厂构造方法需要返回该类的实例对象
1 | class Logger { |
类型转换
使用as
进行强制类型转换
使用is
和is!
来判断是否属于某种类型
1 | dynamic a = 'abc'; |
如果不执行强制类型转换,就不能直接调用String上的方法,因为此时a还是动态类型
继承
dart当中的继承与java基本类似
- 使用
extends
关键字实现继承,只能单继承,具备多态特性 - 子类会继承父类可见的成员,不会继承构造方法
- 子类可以重写父类的方法(重写的方法上可以添加
@override
注解) - 所有类都有公共的基类
Object
构造函数
子类的构造函数会默认隐式调用父类无名无参的构造函数
如果父类当中没有,则需要使用super显式调用
1 | class Demo1{ |
抽象类与接口
抽象类使用abstract
修饰,跟Java基本一样,可以定义抽象方法或者有具体实现的方法(抽象方法并不需要再加abstract修饰)
但是并不存在interface关键字
一个类本身就可以当做接口来使用
1 | class Demo{ |
当然这是非常冗余的,至少属性没什么好重写的
所以实际开发当中通常把抽象类当做以往意义上的接口来使用
Mixins
使用extends只能实现单继承,Mixins就是多继承的一种实现方式
使一个类同时拥有多个类的成员
1 | class A { |
如果A和B当中存在同名方法,那么就是根据with之后的声明顺序
A在前B在后,所以C中实际具备的是B当中的该方法
需要注意的是with后面跟的类
- 不能有显式声明的构造函数
- 只能直接继承自Object(可以省略 extends Object)
- 可以使用implements实现接口
模块化
- 可见性以
library
(库)为单位,差不多可以理解为JavaScript当中的模块 - 每一个dart文件就是一个库
- 以
_
开头声明的类或者函数是在当前库当中私有的,即使其他库引入了该库,也无法在其他库中使用 - 使用
import
来引入一个库文件 - dart的sdk有自带的一套类库,
dart.core
是默认被引入的