1、Dart入口、打印、变量声明、变量命名规则
- 入口函数是main()函数;
- void 表示函数没有返回值;
- 注释方式和js类似;
- 变量:
var或则其他具体类型格式定义;var方式会自动推断类型的。 如果使用具体类型格式定义的变量,后面赋予的值类型必须是规定好的,不然会报错; dart里面有类型校验; - 常量:
const: 值不变,一开始就需要赋值; final: 可以开始不赋值,只能赋值一次。如果是一个函数的值要赋给一个变量,就可以选择final,而不能用const. 如:final date = new DateTime.now(); - dart变量的命名规则:(与其他语言类似)
1、变量名称必须由数字、字母、下划线和美元符号($)组成; 2、注意:标识符开头不能是数字; 3、标识符不能是保留字和关键字; 4、变量的名字是区分大小写的。如age和Age是不同的变量;但一般不建议这么写; 5、标识符(变量名称)一定要见名思义:变量名用名词;方法名用动词。
2、数据类型
常用数据类型: Number: int double String: String Booleans: bool List: 在dart中数组是列表对象,所以大多数人成为它是列表; Map: map是一个键值对相关的对象。键和值都可以是任意类型数据。
注意: 1、字符串:可以用一个单引号、一个双引号包裹;也可以用三个单引号或双引号包裹 如 String str1 = ‘’‘this is name this is name’‘’ 即三个引号的时候会数据可以写多行数据;一个引号的就会只显示到一行上
2、字符串拼接 print(“$str1 $str2”) 或则。print(str1 + str2)
3、double类型的值既可以是int,也可以是double浮点类型;反过来int类型的值不可以赋double类型的值。
4、list 赋值、控制类型、添加数据
var list1 = ['开心', true, 123]
var list2 = <String>['ssdg', 'etwyrey', 'dsgdsgds']; // 指定类型
var list3 = []; list3.add('李四'); list3.add(20);
var list4 = new List(); // 初始化一个数组,新版本废弃,老版本可以使用
var list5 = List.filled(6, ''); list[1]= '历史'; // 定义一个固定长度的数据, 参数表示长度、填充值; 修改内容; 不能在用list5.add()增加数据了,因为长度已固定;所以也是没办法改变长度的 如list5.length = 0; 也是错误的表达式。
var list5 = List<String>.filled(6, '');// 制定类型数据
5、定义map的方式:(key必须加上引号)
// 方式一:
var p = {
'name': 'lisi',
'age': 30,
'work': ['农民','码农']
};
print(p['name']); // 获取name的值
//方式二:
var p2 = new Map();
p2['name']='zhagnsan';
p2['age']= 20;
print(p2['name']);
is 关键词判断类型
var str = 'sagsg' // 后台返回的数据
if(str is String){
print('是string类型');
} else if(str is int){
print('是int类型');
}else {
print('是其他类型');
}
3、运算法、条件表达式、类型转换
与其他语言类似: 算术运算符: +
/ ~/(取整) % (取余) ++
关系运算符: == != > < >= <=
逻辑运算符 ! && ||
赋值运算符 基本赋值运算符: = ??= 复合赋值运算符: += -= *= /= %= ~/=
例子:
b ??= 23; // 表示如果b的值为空就把23赋值过去;如果不为空值不变。
条件运算符 if else switch case. 三目运算符 ? : ??
var b;
var a = b ?? 23; // 如果b的值为空就把23赋值给a;如果不为空则把b的值赋值过去。
类型转换 Number ----->转 String : toString() String ---------->转Number: parse()
isEmpty判断变量是否为空: if(str.isEmpty){print(‘str为空’);} 判断变量是否为NaN: if(str.isNaN){print(‘str为NaN’);}
4、List Set Map以及循环语句forEach、where、why、every
List常用属性和方法: 常用属性: length 长度 reversed 翻转 isEmpty 是否为空 isNotEmpty 是否不为空 常用方法: add 增加 addAll 拼接数组 indexOf 查找 传入具体值 remove 删除 传入具体值 removeAt 删除 传入索引值 fillRange 修改 insert(index,value) 指定位置插入 insertAll(index,list) 指定位置插入list toList() 其他类型转list join() list转字符串 split() 字符串转list forEach
数组去重的一种方式:
var l = ['葡萄','香蕉','葡萄','苹果','桃子','桃子','猕猴桃','大枣','蜜瓜'];
var s = new Set();
s.addAll(l);
print(s);
print(s.toList());
5、函数相关
内置方法/函数: print(); 自定义方法: 基本格式:
返回类型 方法名称(int/String 参数1,参数2,...){
方法体
return 返回值
}
注: 1、自定义方法定义可以在入口方法内定义,也可以在外定义;但是最终调用时需要在入口函数内部;函数也有作用域, 2、如果不知道返回值是什么,函数名前面可以不写返回类型,但如果知道尽量写上去; 3、方法传参数的时候尽量也给参数写上类型,这样避免不必要的错误;当然也可以不传的; 4、可选参数、默认参数,如下函数: 5、命名参数,如下: 6、把方法当作参数的方法,如下:
// 可选参数、默认参数
String printUserInfo(String username, [String sex='女', int age]){
...
}
printUserInfo('小明', '女'); // 调用
// 命名参数
String printUserInfo(String username, {String sex='女', int age}){
...
}
printUserInfo('小明', age:30); // 调用
// 把方法当作参数的方法
fn1(){
print('我是fn1打印出来的数据');
}
fn2(fn){fn();}
fn2(fn1); // 调用
7、箭头、匿名、闭包函数
// 定义一个方法判断一个数是否是偶数;
// 定义一个函数打印1-n所有的偶数。
bool isEvenNumber(int n){
if(n%2==0){
return true;
}
return false;
}
printNum(int n){
for(var i=1; i<=n; i++){
if(isEvenNumber(i)){
print(i);
}
}
}
printNum(10); // 调用
// 匿名函数:
var printNum2 = (){
print('我是匿名函数结果');
}
printNum2();
// 自执行函数
((int n){
print(n);
})(12)
6、对象、类
面向对象开发:继承、封装、多态
dart所有的东西都是对象,所有的对象都继承自object类。 dart是一门使用类和单继承的面向对象语言,多有的对象都是类的实例,并且所有的类都是object的子类; 一个类通常由属性和方法组成。
构造函数:默认构造函数、命名构造函数 类class名称的首字母需大写
// 普通
class PersonMsg{
String name='某人';
int age=22;
void printInfo(){
print('${this.name}----------${this.age}');
}
}
// 含有构造方法(函数一运行实例化时就会执行的事件即构造函数)
class PersonMsg2{
String name='某人';
int age=22;
PersonMsg2(){ // 默认构造函数名称和类名一致
print('这是构造函数里面的内容,实例化时立即会执行');
}
void printInfo(){
print('${this.name}----------${this.age}');
}
}
class PersonMsg3{
String name;
int age;
// 默认构造函数
// PersonMsg3(String name, int age){
// this.name = name;
// this.age = age;
//}
// 默认构造函数简写形式
PersonMsg3(this.name, this.age);
// 命名构造函数 (默认构造函数只能有一个;命名构造函数可以有多个)
PersonMsg3.sum(){
print('我是命名构造函数');
}
void printInfo(){
print('${this.name}----------${this.age}');
}
}
void main(){
PersonMsg p1 = new PersonMsg(); // 实例化
print(p1.name);
p1.printInfo();
PersonMsg2 p2 = new PersonMsg2(); // 实例化 此时就会打印出‘这是构造函数里面的内容,实例化时立即会执行’
PersonMsg3 p3 = new PersonMsg3('瓦格纳', 33); // 实例化
p3.printInfo();
PersonMsg3 p4 = new PersonMsg3('李四', 23); // 可以多次实例化
p4.printInfo();
PersonMsg3 p5 = new PersonMsg3.sum(); // 此时就会打印出'我是命名构造函数'
}
注: Dart和其他面向对象的语言不一样,没有public、private、protected等设置变量为私有或公有的; Dart中一般使用_把一个属性或则方法定义成私有的。(ps:使用这种方式必须把该变量提出去不能在一个文件内才会生效!)
dart中可以有默认值,即在构造函数执行之前初始化实例变量
class Rect{
int height;
int width;
Rect():height=2,width=10{
print("${this.height}-----${this.width}");
}
getArea(){
return this.height*this.width;
}
}
void main(){
Rect r = new Rect(); // 实例化 print里面的内容会打印出height的值,说明赋值先于构造函数执行之前。
print(r.getArea());
}
7、类、静态成员、操作符、类的继承
对象操作符: ? 条件运算符:一般用于获取对象中某一变量时,防止该对象下没有此变量。如userInfo?.name as 类型转换 is 类型判断 … 级联操作(连缀操作)
- 在变量或函数前面添加static及表示为静态变量或方法。不用实例化,直接用类名就可以调用静态方法变量,实例化后只能获取非静态数据。
- 静态成员不能访问非静态成员;反之非静态成员可以访问静态成员;
类的继承:子类可以继承、扩展父类方法,还可以重写父类方法
class People {
String name;
num age;
People(this.name,this.age);
void printInfo(){
print('${this.name}------${this.age}');
}
}
class Web extend People{
String sex; // 如果有新的参数可以定义
Web(String name, num age, String sex): super(name,age){ // 类Web继承于People,因为类People有参数,所以Web也应该设置
this.sex = sex;
}
run(){ // Web自己自定义函数
print('${this.name}------${this.age}-----${this.sex}');
}
@override // 建议复写父类方法时添加这个关键字,也可以不加
void printInfo(){
print('姓名:${this.name}------年龄:${this.age}');
}
}
main() {
Web web1 = new Web('小李', 20, '男');
web1.printInfo(); // 小李------20
web1.run(); // 小李------20-----男
}
注: 如果是命名构造函数也是可以的,父类变成People.xxxx(this.name,this.age); 子类变成Web(String name, num age, String sex): super.xxxx(name,age){}
8、抽象类、 多态 、接口
抽象类abstract:主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。
多态:就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现。
接口:关键字implements 定义规范的。
extends抽象类 和 implements的区别: 1、如果要复用抽象类里面的方法,并且要用抽象方法约束子类的话我们就用extends继承抽象类; 2、如果只是把抽象类当作标准的话我们就用implements实现抽象类。
一个类实现多个接口
abstract class A {
String name;
printA();
}
abstract class B {
printB();
}
class C implements A,B { // 可以多接口
@override
String name;
@override
printA(){print('printA');}
@override
printB(){return null;}
}
注:可以多接口 不能多继承;所以又有一个新的属性Mixins
9、Mixins
关键字是with 注意: 1、作为mixins的类只能继承自Object,不能继承其他类;(如下面的A B类不能extends继承其他的类) 2、作为mixins的类不能有构造函数;(如下面的A B类不能写构造函数,如果A类里必须有构造函数,则可以写出class C extents A width B 这样就可以实现了。) 3、一个类可以mixins多个mixins类; 4、继承或mixins按顺序,如果有相同的方法和属性时,后面的会覆盖前面的; 5、mixins绝不是继承,也不是接口,而是一种全新的特性。
class A {
String name;
printA(){print('printA');}
}
class B {
printB(){return null;}
}
class C width A,B { // 类C中包含A B当中所有的属性和方法
}
main(){
C c = new C();
c.printA();
c.printB();
print(c.name);
// 类型
print(c is C); // true
print(c is A); // true
print(c is B); // true
}
10、泛型、泛型类、泛型方法、泛型接口
函数代码冗余,合并。
class MyList<T> {
List list = <T>[];
void add(T value){
this.list.add(value);
}
List getList() {
return list;
}
}
main(){
MyList list = new MyList<int>();
list.add(12);
list.add(33);
print(list.getList());
}
11、自定义库、系统库、第三方库的使用
1、只使用库中有部分隐藏、部分使用的功能:hide show 如:import ‘http://xxxx.c’ hide foo;
1、空安全:? 可空类型
// 变量
String? username = '张三'; // String? 表示username是一个可空类型; 如果不加?号就会报错
username = null;
print(username);
// 函数
String? getData(apiUrl){ // 如果不加问号,就不能返回null
if(apiUrl!=null){
return "this is server data";
}
return null;
}
2、类型断言 :! 3、late: 关键词主要是为了延迟初始化 4、required: 必传参数
|