• 主页
  • 归档
  • 分类
  • 照片墙
所有文章 友情链接 关于我

  • 主页
  • 归档
  • 分类
  • 照片墙
  1. 1. 函数相关
    1. 1.1. 可选参数
    2. 1.2. 匿名函数和箭头函数
    3. 1.3. 级联调用
  2. 2. 面向对象
    1. 2.1. 计算属性
    2. 2.2. 构造函数
      1. 2.2.1. 常量对象
      2. 2.2.2. 工厂构造方法
    3. 2.3. 类型转换
    4. 2.4. 继承
      1. 2.4.1. 构造函数
    5. 2.5. 抽象类与接口
    6. 2.6. Mixins
  3. 3. 模块化

dart初见(2)

2019-10-06 21:08:37
总字数 1.9k
预计阅读时间 7 分钟

函数相关

dart当中函数也是一个对象,具备共同的抽象类Function
因为是抽象类,所以不能直接用其执行new创建对象

可选参数

dart在定义函数的时候可以在形参表的末尾添加可选参数
有命名参数和匿名参数两种形式

1
2
3
4
5
6
7
8
9
10
11
12
13
void main() {
func1('Sookie', c: true, b: 10);
func2('Sookie', 20, false);
}
// 命名可选参数
void func1(String a, {int b, bool c}) {
print('a=${a},b=${b},c=${c}');
}
// 匿名可选参数
void func2(String a, [int b = 100 ,bool c]) {
// 可以给可选参数指定默认值
print('a=${a},b=${b},c=${c}');
}

命名的可选参数因为传参时指定形参名称,所以就不会强制顺序的匹配了
可选参数的声明必须在形参表的末尾

匿名函数和箭头函数

匿名函数

1
2
3
(参数1, 参数2 ...) {
函数体
}

匿名函数不能声明返回值类型,或者说它的返回值是任意类型的,相当于是dynamic

dynamic并不算一种类型,只是作为一个关键字表示动态类型
就像var也是关键字,但是会执行类型推导

箭头函数

1
(参数1, 参数2 ...) => 返回值

箭头函数只能有一个表达式作为返回值,而不能有其他语句
函数对象都可以使用变量进行接收

级联调用

dart当中使用..来实现级联调用

1
2
3
4
5
6
List list1 = [10,15,20];
list1..add(19)..remove(10);
// 相当于
List list2 = [10,15,20];
list2.add(19);
list2.remove(10);

面向对象

使用class关键字来声明一个类,创建对象时new关键字可以省略
dart中不支持函数重载

可以使用.来访问对象的成员
当然如果变量是null会报空指针的错误
可以判断是否为null
也可以使用?.操作符,相当于自带判断是否为null,如果是null就不执行调用

类如果实现了call函数,那么它的实例就可以直接当做函数来执行调用

1
2
3
4
5
6
7
8
9
10
void main() {
Demo demo = new Demo();
demo('hello');
}

class Demo{
void call(String msg) {
print(msg);
}
}

计算属性

对于不是固定值,而是需要使用一些逻辑获得计算结果的情况
我们可以将其定义为类当中的一个函数,也可以使用计算属性

计算属性分为get和set两种

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void main() {
Rectangle rect = new Rectangle();
rect.width = 10.9;
rect.height = 20.3;
print(rect.area); // 221.27

rect.area = 100;
print(rect.width); // 5.0
}

class Rectangle {
num width, height;

num get area {
return width * height;
}
void set area(num value) {
this.height = 20;
this.width = value / 20;
}
}

它本身当然是个函数,也可以使用箭头函数的写法

构造函数

定义一个类时,如果不写构造函数,会默认提供一个无参的构造函数
支持匿名构造函数与命名构造函数两种
构造函数也不能被重载,如果要实现一个类有多个构造函数,就必须使用命名构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person {
String name;
int age;
// 匿名构造函数
Person(String name, int age) {
this.name = name;
this.age = age;
}
// 也可以写作
// Person(this.name, this.age);

// 命名构造函数
Person.withName(String name) {
this.name = name;
}
}

命名构造函数调用时写作 new Person.withName(‘sookie’)

对于final修饰的类属性,想要在构造函数进行初始化,只能使用这种语法糖的形式来写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person {
final String name;
int age;

Person(this.name, this.age);
Person.withName(this.name);
// 下面的方式是报错的
// Person(String name, int age) {
// this.name = name;
// this.age = age;
// }
// 这种方式当然也报错
// Person.withName(String name) {
// this.name = name;
// }
}
常量对象
1
2
3
4
5
6
7
8
9
10
void main() {
const Person p = const Person('Sookie', 18);
print(p.name);
}

class Person {
final String name;
final int age;
const Person(this.name, this.age);
}
工厂构造方法

dart自带了工厂设计模式的实现,工厂构造方法需要返回该类的实例对象

1
2
3
4
5
6
7
8
9
10
class Logger {
String name;
static final Map<String, Logger> _cache = new Map();
factory Logger(String name) {
if(!_cache.containsKey(name)) {
_cache[name] = new Logger(name);
}
return _cache[name];
}
}

类型转换

使用as进行强制类型转换
使用is和is!来判断是否属于某种类型

1
2
3
4
dynamic a = 'abc';
if(a is String) {
print((a as String).toUpperCase());
}

如果不执行强制类型转换,就不能直接调用String上的方法,因为此时a还是动态类型

继承

dart当中的继承与java基本类似

  • 使用extends关键字实现继承,只能单继承,具备多态特性
  • 子类会继承父类可见的成员,不会继承构造方法
  • 子类可以重写父类的方法(重写的方法上可以添加@override注解)
  • 所有类都有公共的基类Object
构造函数

子类的构造函数会默认隐式调用父类无名无参的构造函数
如果父类当中没有,则需要使用super显式调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Demo1{
String name;
Demo1(String name) {
print('Demo1:${name}');
}
Demo1.withName(String name) {
this.name = name;
}
}

class Demo2 extends Demo1 {
// 显式调用父类的匿名构造函数
Demo2(String name):super(name) {
print('Demo2:${name}');
}
// 显式调用父类的命名构造函数
Demo2.withName(String name):super.withName(name) {
this.name = name;
}
}

抽象类与接口

抽象类使用abstract修饰,跟Java基本一样,可以定义抽象方法或者有具体实现的方法(抽象方法并不需要再加abstract修饰)
但是并不存在interface关键字
一个类本身就可以当做接口来使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Demo{
String name;
void test(String msg) {
print(msg);
}
}
// 如果作为接口使用,就必须重写所有的属性与方法
class Demo1 implements Demo {
@override
String name;

@override
void test(String msg) {
// TODO: implement test
}
}

当然这是非常冗余的,至少属性没什么好重写的
所以实际开发当中通常把抽象类当做以往意义上的接口来使用

Mixins

使用extends只能实现单继承,Mixins就是多继承的一种实现方式
使一个类同时拥有多个类的成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A {
void a() {
print('A.a');
}
}
class B {
void b() {
print('B.b');
}
}
class C with A,B {
//这个类中同时具备A,B两个类的成员
}
// 如果类中不需要添加其他成员,也可以使用如下简写方式
class D = A with B;

如果A和B当中存在同名方法,那么就是根据with之后的声明顺序
A在前B在后,所以C中实际具备的是B当中的该方法

需要注意的是with后面跟的类

  1. 不能有显式声明的构造函数
  2. 只能直接继承自Object(可以省略 extends Object)
  3. 可以使用implements实现接口

模块化

  • 可见性以library(库)为单位,差不多可以理解为JavaScript当中的模块
  • 每一个dart文件就是一个库
  • 以_开头声明的类或者函数是在当前库当中私有的,即使其他库引入了该库,也无法在其他库中使用
  • 使用import来引入一个库文件
  • dart的sdk有自带的一套类库,dart.core是默认被引入的
  • dart
  • flutter

扫一扫,分享到微信

Flutter初见
dart初见(1) 
© 2024 夏夜梦星辰
鲁ICP备19028444号
Power By Hexo
  • 所有文章
  • 友情链接
  • 关于我
{{searchItem.query}}
标签: 分类:
  • maven
  • 持续集成
  • JMS
  • 线程
  • JavaScript
  • ECMAScript6
  • 单元测试
  • Promise
  • Web Worker
  • 函数
  • prototype
  • 模块化
  • 正则表达式
  • 数据库
  • MongoDB
  • 索引
  • 集群
  • 全文检索
  • flutter
  • dart
  • git
  • 版本控制
  • linux
  • shell
  • docker
  • nginx
  • jenkins
  • opencv
  • vim
  • react
  • react native
  • 前端
  • css
  • HTML5
  • Hexo
  • sass
  • Three.js
  • TypeScript
  • Vue
  • 组件化
  • base64
  • webpack
  • nodejs
  • gulp
  • TensorFlow
  • 机器学习
  • 算法
  • 动态规划
  • 数据结构
  • Java
  • JavaScript
  • MongoDB
  • flutter
  • Git
  • linux
  • react
  • 前端杂烩
  • 男生女生
  • 算法
  • 十年饮冰,难凉热血
  • †少女癌†
  • 猫与向日葵
  • coderfun
  • JENKINS
  • API管理后台
愿你最终能接纳每一面每一种的自己
独自活着便是团圆