dart、flutter学习记录

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:主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。

dart、flutter学习记录_第1张图片

多态:就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现。

接口:关键字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: 必传参数

你可能感兴趣的:(Dart,flutter,学习)