变量
Dart定义变量时可以不预先定义变量类型,程序会自动推断类型
定义变量可以通过 var 关键字来申明变量
var name = '李白';
int age = 99;
常量
Dart定义常量用 final 和 const 关键字来修饰符
const值不变,一开始就得赋值
final 可以开始不赋值,但只能赋值一次
final 不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化
常量是永远不改量的量,用final或const修饰它,而不是使用var或其他变量类型
// const 常量
const PI = 3.14159;
print('PI: $PI');
// final 常量
final PI_2 = 3.1415;
print('final常量 PI_2: $PI_2');
final a = new DateTime.now();
print(a); // 2020-03-05 12:02:05.759293
// const a = new DateTime.now(); // 报错
// final 和 const 区别:
// final 可以开始不赋值,但只能赋一次;
// final不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化。
类
new一个对象的时候,new关键字可以省略。
class Person(){
}
main(){
Person p = Person();
}
构造函数
class Person{
String name;
num age;
Person(this.name,this.age);
//以上写法等同于以下
Person(String name,num age){
this.name = name;
this.age = age;
}
}
命名构造函数
Dart不支持构造函数重载,但是可以用可选参数代替。命名构造函数也是可以代替java的重载的。
class Person{
String name;
num age;
Person.haha(){
}
}
main(){
Person p = new Person.haha();
}
继承
主要概念基本同java相同,唯一有区别的就是子构造继承父构造的声明方式
这里是通过super+初始化列表的方式调用父类的构造函数。
class Children extends Person{
Children(String name,num age):super(name,age){
}
}
抽象类
抽象类声明与java相同,都是abstract关键字声明,抽象方法则与之不同。
抽象方法在Dart中声明方式不加方法体既是抽象方法。
abstract class Animal{
eat();//抽象方法
}
多态
定义:允许将子类类型的指针赋值给父类类型的指针,同一个函数调用会有不同的执行效果。
父类定义一个方法不去实现,让每个子类实现,每个子类有不同的表现。
class Dog extends Animal{
@override
eat(){
print("吃骨头");
}
}
main(){
Animal dog = new Dog();
dog.eat();
}
接口
dart没有interface关键字定义接口,而是普通类和抽象类都可以被当做接口被实现。
同样使用implements关键字进行实现。
但是dart的接口有点奇怪,如果实现的类是普通类,会将普通类和抽象类中的属性和方法全部需要复写一遍。
而因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像java接口那样的方式,一般会使用抽象类。
建议使用抽象类定义接口
泛型
泛型是为了解决类,方法,接口的重用性,以及对不特定数据类型的支持(类型校验)。
Dart的泛型和java基本相同。
T getData<T>(T value){
return value;
}
新概念
mixins
mixins的中文意思是混入,就是在类中混入其他功能,
在Dart中可以用mixins实现类似多继承的功能。
因为mixins随着Dart的版本一直在变,以下示例的是2.x版本使用mixins的条件。
1,作为mixins的类只能继承自Object类,不能继承其他类。
2,作为mixins的类不能有构造函数。
3,一个类可以mixins多个mixins类。
4,mixins绝不是继承也不是接口,而是一种全新的特性。
5,如果两个mixins类里有相同名称的方法,会调用后面的mixins类。
class A{
a(){}
run(){}
}
class B{
b(){}
run(){}
}
class C with A,B{
}
main(){
C c = new C();
c.a();
c.b();
c.run();//会打印后者,后者会覆盖前者,就是B里的run
c is A;//true
c is B;//true
c is C;//true
}
计算属性
class Rect{
get area{
return this.height * this.width;
}
set
}
//调用
Rect rect = new Rect();
rect.area;
初始化列表
Dart我们可以在构造函数运行之前初始化实例变量。
这种写法来自c++,效率比域初始化高。
class Rect{
Rect():height=11,width=2{
}
}
对象操作符
【?】 条件运算符
【as】 类型转换,类似java的强转
【is】 类型判断,类似java的instanceof,这略过
【..】 连级操作(连缀),类似构建者模式,链式调用
Person p;
p.getInfo();//空指针
p?.getInfo();//不报错
var p = '';
p = new Person();
(p as Person).getInfo();
p1..name="哈哈"
..age = 20
..print();
async和await关键字
这两个关键字的使用只需记住两点,
1,只有在async方法里面才能使用await关键字调用方法。
2,如果调用别的async方法必须使用await关键字。
async是让方法变成异步,
await是等待方法执行完成。
main() async{ //await必须在async方法里面执行
var result = await testAsync(); //必须使用await调用async方法
print(result);
}
testAsync async{
return 'hello';
}
拓展
Dart中的库
Dart中的库主要有三种。
1,我们自定义的库。
import 'lib/xxx.dart';
2,系统内置库。
import 'dart:math';
import 'dart:io';
import 'dart:convert';
3,Pub包管理系统中的库。
https://pub.dev/packages
https://pub.flutter-io.cn/packages
https://pub.dartlang.org/flutter
1,需要在自己项目根目录新建一个pubspec.yaml文件。
2,在pubspec.yaml文件配置名称,描述,依赖等信息(去网站看步骤即可)。
3,然后运行pub get 命令获取包下载到本地。
4,项目中引入库 import 'package:http/http.dart' as http; 看文档使用。
pubspec.yaml
name:xxx
description:A new flutter project.
dependencies:
http:^0.12.0+2
data_format:^1.0.6
1,冲突解决:
当引入的库里有相同名称标识符的时候,如果是java我们通常是写完整的包名路径来指定。
import 'package:lib1/lib1.dart'
import 'package:lib2/lib2.dart' as lib2;
Element element1 = new Element();//Use Element from lib1
lib2.Element element2 = new lib2.Element();//Use Element from lib2
2,部分导入:
如果只需要导入库的一部分(方法),有两种模式:
模式一:只导入需要的部分(方法),使用show关键字,如下面例子所示:
import 'package:lib1/lib1.dart' show foo;
模式一:隐藏不需要的部分(方法),使用hide关键字,如下例子所示。
import 'package:lib2/lib2.dart' hide foo;
3,延时加载:
懒加载的最大好处是可以减少APP的启动时间。
懒加载使用deferred as关键字来指定,如下例子所示。
import 'package:deferred/hello.dart' deferred as hello;
当需要使用的时候,需要使用loadLibrary()方法来加载。
greet() async{
await hello.loadLibrary();
hello.printGreeting();
}
4,part(分片)
一般库太大了用此关键字把库分成很多片段,使用时再进行导入
网友评论