Dart语法
一 、变量
dart是有类型判断的,所以我们可以使用变量类型声明变量,也可以使用var定义变量
var str = "hello world";
var num = 1234;
String str1 = "你好世界";
int num1 = 12345;
print(str);
print(str1);
print(num);
print(num1);
一 、常量
常量有两种声明方式(const和final关键字),常量不可以修改
const a = "12345";
// a = "45678";//常量不可修改,这种写法会报错
print(a);
final b = false;
// b = true;
print(b);
//------------区别--------------
final c = new DateTime.now();
print(c);
// const d = new DateTime.now();//该写法会报错
final和const的区别在于final可以开始不赋值,只能赋值一次;final是运行时常量,运行时第一次使用才会初始化
三 、常用数据类型
Numbers(数值):
int
double
String(字符串):
String
Booleans:
bool
List(数组):
在dart中,数组是列表对象,所以大多数人只称他们为列表\
Maps(字典)
通常来说Map是一个键值对相关的对象,键和值是任何类型的对象,每个
- 字符串类型
//单引号双引号都可以定义字符串类型
String a = "1111";
String b = '2222';
//三个单引号或者双引号包裹的内容可以多行显示
var ss = """
666
777
888
""";
print(a);
print(b);
print(ss);
//字符串拼接(引用和kotlin一样)
print("$a $b");
print(a + " " + b);
- 数值类型
int a = 123;
double b = 234.5;
- 布尔类型(略)
- List集合类型
//方式一
var list = ["111","222"];
print(list);
print(list.length);
print(list[1]);
//方式二
var list2 = new List();
list2.add("abc");
list2.add("def");
print(list2);
print(list2[0]);
//指定类型
var list3 = new List<String>();
list3.add("value");
print(list3);
- Maps类型
//第一种方式
var map = {
"name" : "张三",
"age" : 22,
"work":['篮球','唱跳']
};
print(map["name"]);
print(map['work']);
//第二种方式
var mp = new Map();
mp['name'] = '李四';
mp['age'] = 25;
mp['work'] = ['篮球','唱跳'];
print(mp['age']);
print(mp['work']);
- 判断数据类型(is关键字)
// var aa = '1245678';
var aa = 123;
if(aa is String) {
print("我是字符串类型");
} else if (aa is int) {
print("我是int类型");
}
四 、运算符
算术运算符
+ - * / ~/(取整) %
关系运算符
== != > < >= <=
逻辑运算符
! && ||
赋值运算符
基础赋值运算符 = ??=
复合赋值运算符 += -= *= /= %= ~/=
条件表达式
if else switch case
三目运算符(和Java中的三元运算符一样)
??运算符(问号前面的对象不为空赋值问号前面的,为空则赋值问号后面的值)
var a;
var b = a ?? 10;
print(b);
//其他运算符和java中一致,在此略过
类型转换
//String 转 int
var xxx = "123";
if(xxx.isNotEmpty) {
var b = int.parse(xxx);
print(b);
}
//double 转 String
var yyy = 12.5;
var zzz = yyy.toString();
print(zzz);
//try ... catch
var ooo = "12.5";
try{
var ppp = int.parse(ooo);
print(ppp);
}catch(err){
print("类型转换错误");
}
五 、循环语句(for,whil, do…whil,continue,break与java完全一致略过)
六 、list set map
List
- 常用属性
-
length 长度
-
reversed 反转
-
isEmpty 是否为空
-
isNoEmpty 是否不为空
- 常用方法
- add 添加元素
- addAll 合并数组
- indexOf 查找元素(传入元素值)
- remove 删除(传入元素值)
- removeAt 删除(传入索引)
- fillRange 修改
- insert(index,value) 在指定位置插入元素
- insertAll(index,list) 在指定位置插入list
- toList() 准换为List类型
- join() List转换为字符串
- split() 字符串转换为List
- forEach
- map
- where
- any
- every
//fillRange(start,end,values......) 前闭后开区间
var list = new List();
list.add("111");
list.add("222");
list.add("333");
// list.fillRange(0, 2,'aaa');
print(list);
//join 将list转换成string
var join = list.join("-");
print((join is String).toString() + " "+ join);
//split
var ss = "111-222-333";
print(ss.split("-"));
Set
//set集合不能出现相同元素
var list = ['111','222','3333','222','3333'];
print(list.toSet());
Map
- 常用属性
-
keys 获取所有的key值
-
values 获取所有value值
-
isEmpty 是否为空
-
isNoEmpty 是否不为空
- 常用方法
- remove(key) 删除指定键值对
- addAll 合并键值对
- containsValue 是否包含该value
- forEach
- map
- where
- any
- every
通用方法
var list = [1,2,3,4,5,6,7,8,9];
list.forEach((element) {
print(element);
});
var newList = list.map((value){
return value*2;
});
print(newList.toList());
var wList = list.where((element) {
return element > 5;
});
print(wList);
var f = list.any((element){
//只要有一个满足条件就返回true
return element > 5;
});
print(f);
var v = list.every((element){
//每一个元素都满足这个条件就返回true
return element > 2;
});
print(v);
//--------map--------
var map = {
"name" : "张三",
"age" : "23"
};
map.forEach((key, value) {
print("$key $value");
});
七 、函数
//可选参数
void printInfo(String name, [int age]) {
if (age != null) {
print("$name --- $age");
} else {
print("$name --- 年龄保密");
}
}
printInfo("张三");
printInfo("李四",20);
//默认参数
void printInfo2(String name, [String sex= '男',int age]) {
if (age != null) {
print("$name --$sex-- $age");
} else {
print("$name --$sex-- 年龄保密");
}
}
printInfo2("张三");
printInfo2("李四",'女');
printInfo2("王五",'男',25);
//命名参数
void printInfo3(String name, {String sex= '男',int age}) {
if (age != null) {
print("$name --$sex-- $age");
} else {
print("$name --$sex-- 年龄保密");
}
}
printInfo3("张三",age: 54);
//箭头函数
var add = (int a,int b)=>a+b;
print(add(1,2));
var list = [1,2,3,4,5];
var map = list.map((e) => e > 2?e*2 : e);
print(map.toList());
//匿名函数
var ni = (){
print("object");
};
ni();
//自执行函数
((String name){
print("$name我是自执行函数");
})("啦啦啦,");
//递归函数
int digui(int index){
if(index == 1) {
return 1;
}
var ss = digui(index-1);
return index * ss;
}
print(digui(5));
//闭包
fun(){
var a = 123;//不污染全局 常驻内存
return(){
a++;
print(a);
};
}
var b = fun();
b();
b();
b();
七 、类,面向对象(oop)
1.继承,封装,多态
封装:封装是对象和类概念的主要特征,封装,把客观事物封装成抽象的类,并且把自己的部分属性和方法提供给其他对象调用, 而一部分属性和方法则隐藏。
继承:他可以使用现有类的功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
多态:允许将子类的类型的指针赋值给父类类型的指针,同一个函数调用会有不同的执行效果
Dart是一门使用类和单继承的面向对象语言,所有的对象都是类的实例,并且所有的类都是Object的子类
class Person{
//私有化变量
String _name ;
int age;
//默认构造函数简写
// Person(this.name,this.age);
//构造方法常用实现
// Person(String name ,int age){
// _name = name;
// this.age = age;
// }
//初始化实例变量 在构造方法中可以在初始化之前给变量赋值(先赋值后执行函数)
Person():_name='山大王',age = 18{
}
get getName{
return _name;
}
set setname(String name){
_name = name;
}
//命名构造函数
Person.setInfo(String name,int age){
_name = name;
this.age = age;
}
void printInfo(){
print('$_name $age');
}
}
/*var person = Person.setInfo('张三', 12);
person.printInfo();*/
//私有化属性名称前加 _ 且对应的类要位于独立的文件中
var person = Person.setInfo('张三', 12);
print(person.age);//可以正常访问
// print(person._name);//无法访问 报错
//get方法 可以使用访问属性的方式访问get方法
print(person.getName);
//set方法
person.setname = '李四';
print(person.getName);
//1. 静态成员 使用status修饰
//2. 静态方法不能访问非静态成员,非静态方法可以访问静态成员
2. 继承,抽象,多态,接口,Mixins
/**
* 类的继承:
* 1.子类使用extends关键词继承父类
* 2.子类会继承父类可见的属性和方法,构造方法除外
* 3.子类能复写父类的方法 getter和setter
*/
/**
* 抽象类:
* 1、抽象类通过abstract 关键字来定义
* 2、Dart中的抽象方法不能用abstract声明,Dart中没有方法体的方法我们称为抽象方法。
* 3、如果子类继承抽象类必须得实现里面的抽象方法
* 4、如果把抽象类当做接口实现的话必须得实现抽象类里面定义的所有属性和方法。
* 5、抽象类不能被实例化,只有继承它的子类可以
* extends抽象类 和 implements的区别:
* 1、如果要复用抽象类里面的方法,并且要用抽象方法约束自类的话我们就用extends继承抽象类
* 2、如果只是把抽象类当做标准的话我们就用implements实现抽象类
*/
/**
* Datr中的多态:
* 允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果 。
* 子类的实例赋值给父类的引用
* 多态就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现。
*/
/**
* Datr中的接口:
* 和Java一样,dart也有接口,但是和Java还是有区别的。
* 首先,dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现。
* 同样使用implements关键字进行实现。
* 但是dart的接口有点奇怪,如果实现的类是普通类,会将普通类和抽象中的属性的方法全部需要覆写一遍。
* 而因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像Java接口那样的方式,一般会使用抽象类。
* 建议使用抽象类定义接口。
*/
/**
* mixins的中文意思是混入,就是在类中混入其他功能。
* 在Dart中可以使用mixins实现类似多继承的功能
* 因为mixins使用的条件,随着Dart版本一直在变,这里讲的是Dart2.x中使用mixins的条件:
* 1、作为mixins的类只能继承自Object,不能继承其他类
* 2、作为mixins的类不能有构造函数
* 3、一个类可以mixins多个mixins类
* 4、mixins绝不是继承,也不是接口,而是一种全新的特性
* mixins的实例类型是什么?
* 很简单,mixins的类型就是其超类的子类型。
*
* 1.同时使用extends和with,如果如果继承和混入的类中有相同的方法混入的方法会覆盖继承的方法
* 2.如果with多个类有相同的方法时,位于后面的类中方法会覆盖前面的方法
*/
class A {
String info = "this is A";
void printA() {
print("A");
}
}
class B {
void printB() {
print("B");
}
}
class C with A, B {}
void main() {
var c = new C();
c.printA();
c.printB();
print(c.info);
var c=new C();
print(c is C); //true
print(c is A); //true
print(c is B); //true
// var a=new A();
// print(a is Object);
}
3. 泛型
/*
通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)
*/
//只能返回string类型的数据
// String getData(String value){
// return value;
// }
//同时支持返回 string类型 和int类型 (代码冗余)
// String getData1(String value){
// return value;
// }
// int getData2(int value){
// return value;
// }
//同时返回 string类型 和number类型 不指定类型可以解决这个问题
// getData(value){
// return value;
// }
//不指定类型放弃了类型检查。我们现在想实现的是传入什么 返回什么。比如:传入number 类型必须返回number类型 传入 string类型必须返回string类型
// T getData<T>(T value){
// return value;
// }
getData<T>(T value){
return value;
}
void main(){
// print(getData(21));
// print(getData('xxx'));
// getData<String>('你好');
print(getData<int>(12));
}
八 、自定义库,系统库,第三方库
0.介绍
/*
前面介绍Dart基础知识的时候基本上都是在一个文件里面编写Dart代码的,但实际开发中不可能这么写,模块化很重要,所以这就需要使用到库的概念。
在Dart中,库的使用时通过import关键字引入的。
library指令可以创建一个库,每个Dart文件都是一个库,即使没有使用library指令来指定。
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; 看文档使用
*/
1.async和await
/*
async和await
这两个关键字的使用只需要记住两点:
只有async方法才能使用await关键字调用方法
如果调用别的async方法必须使用await关键字
async是让方法变成异步。
await是等待异步方法执行完成。
*/
void main() async{
var result = await testAsync();
print(result);
}
//异步方法
testAsync() async{
return 'Hello async';
}
2.引入第三方库
/*
pub包管理系统:
1、从下面网址找到要用的库
https://pub.dev/packages
https://pub.flutter-io.cn/packages
https://pub.dartlang.org/flutter/
2、创建一个pubspec.yaml文件,内容如下
name: xxx
description: A new flutter module project.
dependencies:
http: ^0.12.0+2
date_format: ^1.0.6
3、配置dependencies
4、运行pub get 获取远程库
5、看文档引入库使用
*/
import 'dart:convert' as convert;
import 'package:http/http.dart' as http;
import 'package:date_format/date_format.dart';
main() async {
// var url = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1";
// // Await the http get response, then decode the json-formatted responce.
// var response = await http.get(url);
// if (response.statusCode == 200) {
// var jsonResponse = convert.jsonDecode(response.body);
// print(jsonResponse);
// } else {
// print("Request failed with status: ${response.statusCode}.");
// }
print(formatDate(DateTime(1989, 2, 21), [yyyy, '*', mm, '*', dd]));
}
3.库重命名,冲突解决
/*
1、冲突解决
当引入两个库中有相同名称标识符的时候,如果是java通常我们通过写上完整的包名路径来指定使用的具体标识符,甚至不用import都可以,但是Dart里面是必须import的。当冲突的时候,可以使用as关键字来指定库的前缀。如下例子所示:
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
Element element1 = new Element(); // Uses Element from lib1.
lib2.Element element2 = new lib2.Element(); // Uses Element from lib2.
*/
import 'lib/Person1.dart';
import 'lib/Person2.dart' as lib;
main(List<String> args) {
Person p1=new Person('张三', 20);
p1.printInfo();
lib.Person p2=new lib.Person('李四', 20);
p2.printInfo();
}
4.部分导入库
/*
部分导入
如果只需要导入库的一部分,有两种模式:
模式一:只导入需要的部分,使用show关键字,如下例子所示:
import 'package:lib1/lib1.dart' show foo;
模式二:隐藏不需要的部分,使用hide关键字,如下例子所示:
import 'package:lib2/lib2.dart' hide foo;
*/
// import 'lib/myMath.dart' show getAge;
import 'lib/myMath.dart' hide getName;
void main(){
// getName();
getAge();
}
5.延迟加载
/*
延迟加载
也称为懒加载,可以在需要的时候再进行加载。
懒加载的最大好处是可以减少APP的启动时间。
懒加载使用deferred as关键字来指定,如下例子所示:
import 'package:deferred/hello.dart' deferred as hello;
当需要使用的时候,需要使用loadLibrary()方法来加载:
greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
*/