1. 入口方法、变量、常量
1.1 入口方法main方法
void main() {
}
1.2 常量变量
- var 变量
- const 常量
- final 常量
const 与 final区别
final 可以开始不赋值,只能赋值一次;而final不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化。
2. 数据类型
2.1 字符串类型 String
字符串定义可以用单引号,“” 也可以用‘双引号’,成对出现。
String str1 = ‘this is str1’;
三个单引号(双引号) 可以定义多行字符串
字符串的拼接
print($str1 $str2);
print(str1 + str2);
2.2 数值类型 int double
int
int a = 123
double b = 23.5
print(a);
double既可以是整型 也可以是浮点型
2.3 布尔类型 bool
bool flag1 = true;
var l1 = ['aaa','bbb','ccc'];
print(l1.length);
2.4 集合类型 List
var l2 = new List();
l2.add('张三');
print(l2[0]);
var l3 = new List<String>();
l3.add('张三');
print(l3);
2.5 Map类型 Map
var person = {
"name":"张三",
"age":20,
"work":["程序员","快递员"]
}
print(person["name"]);
var p = new Map();
p["name"] = "李四";
2.6 类型判断
is 关键字判断类型
3. 算数运算符
3.1 算数运算符
+ - * /
~/ 取整
3.2 关系运算符
关系运算符 == != > < >= <=
3.3 逻辑运算符
逻辑运算符 ! && ||
3.4 赋值运算符
赋值运算符 == ??= 从右向左
int b;
b ??= 23; //如果b为空 把23赋值给b
//+= -= *= /= ~/=
a += 3; a = a+3;
3.5 条件表达式
条件表达式 if else switch case
if() {
}else {
}
三目运算符 ? :
?? 运算符
3.6 类型转换
数值类型转换成String toString()
String转换成int int.parse()
try catch
其他类型转换布尔类型
isEmpty:判断字符串是否为空
NaN not a number isNaN 是否是数值
自增自减 ++ -- 在赋值运算中,如果++在前边,先运算后赋值。如果++在后边,先赋值后运算。
a++; //a=a+1;
a--; //a = a-1;
var a = 10;
var b = a++;
print(a); //11
print(b)://10
4. 循环语句
4.1 for循环
for(int i =1;i<=10;i++) {
print(i);
}
//先执行print(i) 再执行i++
4.2 while do...while
while(){
}
do{
}while()
4.3 break continue 用法区别
break 跳出当前循环,只能跳出一层循环
continue 跳过当次循环,循环还会继续执行
5. List Set Map
5.1 List
属性
- length
- isEmpty
- isNotEmpty
- reversed 对列表倒序排序
方法
add('桃子') 增加元素
addAll() 增加数组里的元素
indexOf('苹果') 查找数据 查找不到返回-1 找到返回index
remove('西瓜')
fillRange 修改
insert 插入
insertAll 插入多个
myList.join('') //list转换成字符串
str.split('-') 字符串转换成list
5.2 Set
Set 集合 去重
5.3 Map
常用属性
keys
values
isEmpty
isNotEmpty
常用方法
addAll
remove
containsValue
5.4 forEach map where any every
myList.forEach((value) {
print("%value");
});
map
List myList = [1,3,4];
var newList = myList.map((value){
return value*2;
});
print(newList.toList());//[2,6,8]
where
List myList = [1,3,4,5,7,8,9];
var newList = myList.where((value){
return value>5;
});
print(newList.toList());//[7,8,9]
any
List myList = [1,3,4,5,7,8,9];
var f = myList.any((value){ //只要集合里面有满足条件的就返回true
return value>5;
});
print(f);//true
every
List myList = [1,3,4,5,7,8,9];
var f = myList.every((value){ //每一个都满足条件返回true,否则返回false
return value>5;
});
print(f);//false
6. 函数
方法定义
返回类型 方法名称(参数1,参数2,...) {
方法体
return 返回值;
}
void printInfo(){
print('我是一个自定义方法');
}
int getNum() {
var myNum = 123;
return myNum;
}
void main() {
print('');
}
var n = getNum();
print(n);
List getList() {
return ['111','222','333'];
}
可选参数,默认参数
//可选参数
String printUserInfo(String username,[String sex = '男',int age]) {//[可选参数]
if (age != null) {
return "姓名:$username---年龄:$age";
}
return "姓名:$username---年龄保密";
}
print(printUserInfo("张三",20));
命名参数
String printUserInfo(String username,{String sex = '男',int age}) {
if (age != null) {
return "姓名:$username---年龄:$age";
}
return "姓名:$username---年龄保密";
}
print(printUserInfo("张三",age:20));
方法当做参数
var fn = (){
print('我是一个匿名方法');
}
fn();
fn1() {
print('fn1');
}
fn2(fn) {
fn();
}
fn2(fn1);
箭头函数(只能写一行)
List list = ['苹果','香蕉','西瓜'];
//常规写法
list.forEach((value){
print(value);
});
//箭头函数
list.for((value)=>print(value));
List list = [4,1,2,3,4];
//常规写法
var newList = list.map((value){
if (value > 2) {
return value*2;
}
return value;
});
//箭头函数
var newList = list.map((value)=>value>2?value*2:value);
print(newList.toList());
匿名方法
var printNum = (){
print(123);
};
printNum();
自执行方法
((int n){
print(n);
print('我是自执行方法');
})();
方法的递归
var sum = 1;
fn(n) {
sum *= n;
if (n==1) {
return;
}
fn(n-1);
}
fn(5);
print(sum);
闭包
常驻内存,不污染全局
1.全局变量特点:全局变量常驻内存、全局变量污染全局
2.局部变量特点:不常住内存会被垃圾机制回收、不会污染全局
fn() {
var a = 123; /*不会污染全局 常驻内存*/
return() {
a++;
print(a);
};
}
var b = fn();
b(); //124
b(); //125
b(); //126
7. 类
默认构造函数 命名构造函数
默认构造函数只能定义一个
命名构造函数可以定义多个
class Person{
String name;
int age;
//默认构造函数
Person(String name,int age) {
this.name = name;
this.age = age;
print('这是构造函数里面的内容,这个方法在实例化的时候触发');
}
//默认构造函数简写 Person(this.name,this.age);
Person.now(){
print('我是命名构造函数');
}
void getInfo() {
print("$name---$age");
print("${this.name}---${this.age}");
}
void setInfo(int age) {
this.age = age;
}
}
void main() {
var p1 = new person('张三',20);
print(p1.name);
p1.setInfo(28);
}
私有属性、私有方法
使用_
把一个属性或者方法定义成私有。需要把类抽离成一个文件
getter setter
class Rect {
num height;
num width;
Rect(this.height,this.width);
get area{
return this.height*this.width;
}
set areaHeight(value) {
this.height = value;
}
}
void main(){
Rect r = new Rect(10,4);
r.areaHeight = 6;
print("面积:${r.area}");
}
类的初始化列表
class Rect {
int height;
int width;
Rect():height=2,width=10 {
print("${this.height}---${this.width}");
};
get area{
return this.height*this.width;
}
set areaHeight(value) {
this.height = value;
}
}
void main(){
Rect r = new Rect();
print("面积:${r.area}");
}
类中的静态成员
1.使用static
关键字来实现类级别的变量和函数
2.静态方法不能访问非静态成员,非静态方法可以访问静态成员
class Person {
static String name = '张三';
int age = 20;
static void show() {
print(name);
}
void printInfo() { /*非静态方法可以访问静态成员以及非静态成员*/
print(name); //访问静态属性
print(this.age); //访问非静态属性
show();//调用静态方法
}
static void printUserInfo() {//静态方法
print(name);//静态属性
show();//静态方法
}
}
main() {
print(Person.name);
Person.show();
}
对象操作符
? 条件运算符
as 类型转换
is 类型判断
.. 级联操作(连缀)
? 条件运算符
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
main() {
Person p;
p?.printInfo();
}
as 类型转换
var p1;
p1 = '';
p1 = new Person('张三',20);
(p1 as Person).printInfo();
.. 级联操作
Person p1 = new pERSON('张三',20);
p1.printInfo();
p1..name = "李四"
..age = 30
..printInfo();
继承 extends
class Web extends Person {
String sex;
Web(String name,num age,String sex) : super(name, age) {
this.sex = sex;
}
//覆写父类的方法
@override
void printInfo() {
print("姓名:${this.name}---年龄:${this.age}");
}
}
抽象类
抽象类:主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。
抽象方法 没有方法体的方法
- 子类必须实现
- 抽象类不能被实例化
//抽象类
abstract class Animal {
eat(); //抽象方法
}
class Dog extends Animal {
@override
eat() {
return null;
}
}
多态
允许将子类类型的指针赋值给父类类型的指针,同一个函数调用会有不同的执行结果。
子类的实例赋值给父类的引用。
多态就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现。
Animal d = new Dog();
d.eat();
Animal c = new Cat();
c.eat();
接口
使用抽象类定义接口
abstract class Db { //当做接口 接口:就是约定、规范
String uri;
add();
save();
delete();
}
class Mysql implements Db {
@override
String uri;
@override
add() {
}
@override
delete() {
}
@override
save() {
}
}
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() {
}
@override
printB() {
}
}
mixins实现类似多继承的功能
class A {
void printA() {
String info = "this is A";
print("A");
}
}
class B {
void printB() {
print("B");
}
}
class C extends Person with A,B {
}
void main() {
var c = new C();
c.printA();
C.printB();
print(c.info);
}
8. 泛型
解决类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)
//泛型方法
T getData<T>(T value) {
return value;
}
void main() {
getData<String>('你好');
print(getData<int>(12));
}
//泛型类
List list = new List<String>();