学习网址
https://book.flutterchina.club/
final和const的区别:
区别一:final 要求变量只能初始化一次,并不要求赋的值一定是编译时常量,可以是常量也可以不是。而 const 要求在声明时初始化,并且赋值必需为编译时常量。
区别二:final 是惰性初始化,即在运行时第一次使用前才初始化。而 const 是在编译时就确定值了。
类的定义与构造方法
Dart中的类没有访问控制,所以你不需要用private
, protected
, public
等修饰成员变量或成员函数。
class Person {
String name;
int age;
String gender;
Person(this.name, this.age, this.gender);
sayHello() {
print("hello, this is $name, I am $age years old, I am a $gender");
}
}
上面的Person类中有3个成员变量,一个构造方法和一个成员方法,看起来比较奇怪的是Person的构造方法,里面传入的3个参数都是this.xxx
,而且没有大括号{}
包裹的方法体,这种语法是Dart比较独特而简洁的构造方法声明方式,它等同于下面的代码:
Person(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
要调用Person类的成员变量或成员方法,可以用下面的代码:
var p = new Person("zhangsan", 20, "male");
p.sayHello(); // hello, this is zhangsan, I am 20 years old, I am a male
p.age = 50;
p.gender = "female";
p.sayHello(); // hello, this is zhangsan, I am 50 years old, I am a female
Dart中使用extends关键字做类的继承,如果一个类只有命名的构造方法,在继承时需要注意,如下代码:
class Human {
String name;
Human.fromJson(Map data) {
print("Human's fromJson constructor");
}
}
class Man extends Human {
Man.fromJson(Map data) : super.fromJson(data) {
print("Man's fromJson constructor");
}
}
由于Human
类没有默认构造方法,只有一个命名构造方法fromJson
,所以在Man
类继承Human
类时,需要调用父类的fromJson
方法做初始化,而且必须使用Man.fromJson(Map data) : super.fromJson(data)
这种写法,而不是像Java那样将super写到花括号中
。
有时候你仅仅只是在某个类的构造方法中,调用这个类的另一个构造方法,你可以这么写:
class Point {
num x, y;
Point(this.x, this.y);
// 命名构造方法调用了默认的构造方法
Point.alongXAxis(num x) : this(x, 0);
}
类的成员方法
一个类的成员方法是一个函数,为这个类提供某些行为。上面的代码中已经有了一些类的成员方法的定义,这些定义方式跟Java很类似,你可以为某个类的成员变量提供getter/setter方法,如下代码:
class Rectangle {
num left, top, width, height;
// 构造方法传入left, top, width, height几个参数
Rectangle(this.left, this.top, this.width, this.height);
// right, bottom两个成员变量提供getter/setter方法
num get right => left + width;
set right(num value) => left = value - width;
num get bottom => top + height;
set bottom(num value) => top = value - height;
}
抽象类和抽象方法
使用abstract修饰一个类,则这个类是抽象类,抽象类中可以有抽象方法和非抽象方法,抽象方法没有方法体,需要子类去实现,如下代码:
abstract class Doer {
// 抽象方法,没有方法体,需要子类去实现
void doSomething();
// 普通的方法
void greet() {
print("hello world!");
}
}
class EffectiveDoer extends Doer {
// 实现了父类的抽象方法
void doSomething() {
print("I'm doing something...");
}
}
运算符重载
Dart中有类似于C++中的运算符重载语法,比如下面的代码定义了一个向量类,重载了向量的+
-
运算:
class Vector {
num x, y;
Vector(this.x, this.y);
Vector operator +(Vector v) => new Vector(x + v.x, y + v.y);
Vector operator -(Vector v) => new Vector(x - v.x, y - v.y);
printVec() {
print("x: $x, y: $y");
}
}
main() {
Vector v1 = new Vector(1, 2);
Vector v2 = new Vector(3, 4);
(v1 - v2).printVec(); // -2, -2
(v1 + v2).printVec(); // 4, 6
}
枚举类
使用enum关键字定义一个枚举类,这个语法跟Java类似,如下代码:
enum Color { red, green, blue }
mixins
mixins是一个重复使用类中代码的方式,比如下面的代码:
class A {
a() {
print("A's a()");
}
}
class B {
b() {
print("B's b()");
}
}
// 使用with关键字,表示类C是由类A和类B混合而构成
class C = A with B;
main() {
C c = new C();
c.a(); // A's a()
c.b(); // B's b()
}
静态成员变量和静态成员方法
// 类的静态成员变量和静态成员方法
class Cons {
static const name = "zhangsan";
static sayHello() {
print("hello, this is ${Cons.name}");
}
}
main() {
Cons.sayHello(); // hello, this is zhangsan
print(Cons.name); // zhangsan
}
静态成员变量和静态成员方法
// 类的静态成员变量和静态成员方法
class Cons {
static const name = "zhangsan";
static sayHello() {
print("hello, this is ${Cons.name}");
}
}
main() {
Cons.sayHello(); // hello, this is zhangsan
print(Cons.name); // zhangsan
}
泛型(Generics)
Java和C++语言都有泛型,Dart语言也不例外,使用泛型有很多好处,比如:
正确指定泛型类型会产生更好的生成代码。
泛型可以减小代码的复杂度
Dart内置的数据类型List就是一个泛型数据类型,你可以往List中塞任何你想的数据类型比如整型、字符串、布尔值等
Dart库(Libraries)的导入
Dart目前已经有很多的库提供给开发者,许多功能不需要开发者自己去实现,只需要导入对应的包即可,使用import语句来导入某个包,比如下面的代码:
import 'dart:html';
如果你想导入自己写的某个代码文件,使用相对路径即可,例如当前有一个demo.dart文件,跟该文件同级目录下有个util.dart文件,文件代码如下:
// util.dart文件内容
int add(int a, int b) {
return a + b;
}
在demo.dart文件中如果要引用util.dart
文件,使用下面的方式导入:
// demo.dart
import './util.dart';
main() {
print(add(1, 2));
}
你可以使用as
关键字为导入的某个包设置一个前缀,或者说别名,比如下面的代码:
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// Uses Element from lib1.
Element element1 = Element();
// Uses Element from lib2.
lib2.Element element2 = lib2.Element();
你也可以在导入包时使用show
/ hide
关键字来导入某个包中的部分功能,比如下面的代码:
// 只导入foo
import 'package:lib1/lib1.dart' show foo;
// 导入除了foo的所有其他部分
import 'package:lib2/lib2.dart' hide foo;
导入包时使用deferred as
可以让这个包懒加载,懒加载的包只会在该包被使用时得到加载,而不是一开始就加载,比如下面的代码:
import 'package:greetings/hello.dart' deferred as hello;
异步
Dart提供了类似ES7中的async
await
等异步操作,这种异步操作在Flutter开发中会经常遇到,比如网络或其他IO操作,文件选择等都需要用到异步的知识。
async
和await
往往是成对出现的,如果一个方法中有耗时的操作,你需要将这个方法设置成async
,并给其中的耗时操作加上await
关键字,如果这个方法有返回值,你需要将返回值塞到Future
中并返回,如下代码所示:
Future checkVersion() async {
var version = await lookUpVersion();
// Do something with version
}
下面的代码使用Dart从网络获取数据并打印出来:
import 'dart:async';
import 'package:http/http.dart' as http;
Future<String> getNetData() async{
http.Response res = await http.get("http://www.baidu.com");
return res.body;
}
main() {
getNetData().then((str) {
print(str);
});
}
参考:
30分钟掌握 Dart 语言
网友评论