入门
变量
数据类型
dart1.12加入空安全。 在dart中的一切皆是对象,包括数字、布尔值、函数等,它们和Java一样都继承于Object,所以它们的默认值也就是null。在dart主要有: 布尔类型bool、数字类型num(数字类型又分为int,double,并且两者父类都是num)、字符串类型String、集合类型(List, Set, Map)。
结构:【类型】【变量名】= 【赋值】
void variable(){
bool isBool = false;
String name = "flutter";
int age = 1;
double height = 12.1;
print(isBool.runtimeType);
print(name.runtimeType);
print(age.runtimeType);
print(height.runtimeType);
}
细节一:num类型的变量,自带了数学函数Math功能,不像其他语言
double height = -12.1;
print("height ${height.abs()}");
集合
new 关键词是可选的,创建对象,不需要显示声明关键字new。
void collection(){
List<String> colorList = ['red', 'yellow', 'blue', 'green'];
colorList.forEach((String color) => print(color));
print(colorList.map((color) => '1+$color').join(","));
Set<String> colorSet = {'red', 'yellow', 'blue', 'green'};
for (var color in colorSet) {
print(color);
}
Map<String, int> colorMap = {'white': 0xffffffff, 'black':0xff000000};
print(colorMap.containsKey('green'));
print(colorMap.containsValue(0xff000000));
print(colorMap.runtimeType);
}
打印set和map 显示的是_InternalLinkedHashMap,网上有对这个说明。
空安全null safety
从dart 2.12开始,支持空安全。就是在类型后面加个?
void nullSafety(){
String? nullStr;
int? nullInt;
bool? nullBool;
Map<String, int>? nullMap;
String str;
print("is $str");
}
如果使用String str 申明变量,但又不初始化,在使用的时候就会报错误。
late延时/惰性初始化
正式使用它之前必须得保证初始化过了,否则会报错
- 可能不需要该变量,并且初始化它的成本很高。
- 这个变量可能从网络获取。
void main() {
var awesome = Awesome();
print('awesome: ${awesome.isAwesome}');
lateVoid();
}
late String description;
void lateVoid() {
description = 'Flutter!';
print(description);
}
类型推导var、dynamic、object
前面介绍了dart中常用的变量,还可以使用var、dynamic、object用于定义变量,通过这种方式定义变量不需要指定变量类型。
补充:从图上可以知道object是类型的基类。
使用var、dynamic、object,可以不用指明变量类型。他们区别是什么: var,编译时会检测类型,如果类型推断出是string类型,再赋值int,会报错。 dynamic,类型是可变的,先复制string再复制int是可以的,编译时不会揣测数据类型,但是运行时会推断。 Object,类型是可变的,先复制string再复制int是可以的,编译时会检测类型。
void varAndDynamic(){
var str = "flutter";
print(str.runtimeType);
print(str);
dynamic mic = "flutter";
print(mic.runtimeType);
print(mic);
mic.foo();
mic=1;
print(mic.runtimeType);
print(mic);
Object object = "flutter";
print(object.runtimeType);
print(object);
object=1;
print(object.runtimeType);
print(object);
object.foo();
}
Final 和 Const
如果你不想更改一个变量,可以使用关键字 final 或者 const 修饰变量。一个 final 变量只可以被赋值一次;一个 const 变量是一个编译时常量(const 变量同时也是 final 的)。
final:其值在初始化后不可改变; const:只能被设一次值,在声明处赋值,且值必须为编译时常量;用于修饰常量。
void finalAndConst(){
const int age = 20;
final String name = 'Flutter';
print("name $name");
final int count = 2 * 2;
final baz = [1];
baz[0] = 2;
print(baz);
final String finalTimeStamp = DateTime.now().toString();
const String constTimeStamp = DateTime.now().toString();
print("finalTimeStamp $finalTimeStamp");
}
Assert(断言)
在dart中如果条件表达式结果不满足条件(表达式为false),则可以使用 assert 语句中断代码的执行。特别是在Flutter源码中随处可见都是assert断言的使用。注意: 断言只在检查模式(debug调试)下运行有效,如果在生产模式运行,则断言不会执行。
assert(text != null);
assert(urlString.startsWith('https'));
补充
官方不推荐使用forEach方法进行,建议使用for…in替换。
void collection() {
List<String> colorList = ['red', 'yellow', 'blue', 'green'];
colorList.forEach((String color) => print(color));
}
lint语法检测:给出的提示 foreach与fon-in方法pk forEach方法在回调方法出现的弊端。
函数
Dart是一种真正的面向对象的语言,所以即使是函数也是对象,并且有一个类型Function。
函数声明
返回类型,函数名,入参
bool isNull(int? num) {
return num == null;
}
如果函数体内只包含一个表达式,你可以使用简写语法:
bool isNull2 (int? num) => num == null;
Dart函数声明如果没有显式声明返回值类型时会默认当做dynamic处理,注意,函数返回值没有类型推断,不建议使用。
isNull3(int? num) {
return num == null;
}
参数
有两种形式的参数:必要参数 和 可选参数。必要参数定义在参数列表前面,可选参数则定义在必要参数后面。可选参数可以是 命名的 或 位置的。
void upload(String filePath, String fileName, int? fileSize) {
}
void upload2(String filePath, String fileName, {int? fileSize}) {
}
void upload3(String filePath, String fileName, [int? fileSize]) {
}
void testParam(){
upload("/user", "name", 0);
upload2("/user", "name");
upload2("/user", "name", fileSize: 10);
upload3("/user", "name");
upload3("/user", "name", 10);
}
可选命名参数在Flutter中使用非常多。注意,不能同时使用可选的位置参数和可选的命名参数。 命名位置参数,最大的好处是能知道,传递参数的含义,再配上关键词required,required表示这个参数是必须的。
void upload4({required String filePath, required String fileName, int? fileSize}) {
}
upload4(filePath: "/user", fileName: "name");
upload4(filePath: "/user", fileName: "name", fileSize: 10);
类
对象的 成员 由函数和数据(即 方法 和 实例变量)组成。
默认构造函数
如果你没有声明构造函数,那么 Dart 会自动生成一个无参数的构造函数并且该构造函数会调用其父类的无参数构造方法。
class Point{
int x = 0;
int y = 0;
}
Point point = Point();
有参构造函数和命名式构造函数
需要注意的是:使用了有参构造函数和命名式构造函数,那默认的构造函数就无效了。无法直接使用 Point point = Point();
构造函数:声明一个与类名一样的函数即可声明一个构造函数。 命名式构造函数:可以为一个类声明多个命名式构造函数来表达更明确的意图:
class Point{
int x = 0;
int y = 0;
int? z = 0;
Point(double x, double y) {
x = x;
y = y;
}
Point.origin(){
x = 5;
y = 5;
}
Point.fromJson(Map<String, dynamic> json){
x = json['x'];
y = json['y'];
}
void printPoint(){
print("x = $x y = $y");
}
int distanceTo(){
return 0;
}
}
void testPoint(){
Point point = Point(2,2);
point.printPoint();
Point point2 = Point.origin();
point2.printPoint();
Point point3 = Point.fromJson({'x': 1, 'y': 2});
point3.printPoint();
Point? point4;
point4?.printPoint();
}
私有属性、私有方法
-
Dart和其他面向对象语言不一样,Data中没有 public private protected这些访问修饰符合,但是我们可以使用_把一个属性或者方法定义成私有。 -
私有方法必须要抽离在单独文件中,否则不生效。
class PrivateClass{
int _i = 1;
int j = 2;
PrivateClass();
void printContent() {
print("打印变量_i = $_i j = $j");
}
void _printContent2(){
print("打印变量_i = $_i j = $j");
}
}
PrivateClass privateClass = PrivateClass();
privateClass.printContent();
privateClass.j = 3;
privateClass.printContent();
privateClass._i = 3;
privateClass._printContent2();
继承
如果父类没有匿名无参数构造函数,那么子类必须调用父类的其中一个构造函数。
class Person {
String? firstName;
Person.fromJson(Map data) {
print('in Person');
}
void eat() {
print("eat");
}
void play(){
print("play");
}
}
class Teacher extends Person {
Teacher.fromJson(Map data) : super.fromJson(data) {
print('in Teacher');
}
@override
void eat() {
super.play();
print("eat fish");
}
}
void testExtends() {
Teacher teacher = Teacher.fromJson({});
teacher.eat();
}
输出
in Person
in Teacher
play
eat fish
Mixin
Dart 是不支持多继承的,Mixin 是一种在多重继承中复用某个类中代码的方法模式,“组合”类可以访问mixin类的方法、变量而不必成为其子类。使用 with 关键字来使用 Mixin 模式。 定义一个 Person 类,实现吃饭、说话、走路和写代码功能,同时定义一个 Dog 类,实现吃饭、和走路功能:
class Person {
say() {
print('say');
}
}
mixin Eat {
eat() {
print('eat');
}
}
mixin Walk {
walk() {
print('walk');
}
}
mixin Code {
code() {
print('code');
}
}
class Dog with Eat, Walk{}
class Man extends Person with Eat, Walk, Code{}
void testMixin(){
Man man = Man();
man.say();
man.code();
man.eat();
Dog dog = Dog();
dog.eat();
}
打印结果
say
code
eat
eat
Dart之Mixin详解,Flutter中大量使用了这种方式。
|