dart学习
wildwolfer 2024-08-22 13:33:06 阅读 93
Dart 变量
dart是一个强大的脚本类语言,可以不预先定义变量类型 ,自动会类型推断
dart中定义变量的方式 :
1. 可以通过var关键字
2. 可以通过类型来声明变量
3. late延迟声明
声明一个非空变量,但不在声明时初始化。
延迟初始化一个变量。
如:
<code>var str='this is var';code>
String str='this is var';code>
int str2=123;
late int myNumber; // 声明一个未初始化的整型变量
// print(myNumber); // 这会抛出一个错误,因为变量尚未初始化
myNumber = 10; // 在将来的某个时刻初始化变量
print(myNumber); // 这会输出 10
注意: var 后就不要写类型 , 写了类型 不要var 两者都写会报错
Dart 常量:
final 和 const修饰符
const值不变 一开始就得赋值
final 可以开始不赋值 只能赋一次 ;而final不仅有const的编译时常量的特性,最重要的它是运行 时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化
// const date1 = new DateTime.now();
final date2 = new DateTime.now();
print(date2);
永远不改变的量,请使用final或const修饰它,而不是使用var或其他变量类型。
final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere
Dart的命名规则:
1、变量名称必须由数字、字母、下划线和美元符($)组成。
2.注意:标识符开头不能是数字
3.标识符不能是保留字和关键字。
4.变量的名字是区分大小写的如: age和Age是不同的变量。在实际的运用中,也建议,不要用一个单词大小写区分两个变量。
5、标识符(变量名称)一定要见名思意 :变量名称建议用名词,方法名称建议用动词 。
var str1='2134214';code>
//var 2str='xxx'; //错误code>
// var if='124214'; //错误code>
//变量的名字是区分大小写的
var age=20;
var Age=30;
Dart注释:
//注释xxxxxxxxxxx
/*
多行注释
多行注释
多行注释
*/
Dart数据类型
常用数据类型:
Numbers(数值):
double
int a = 20;
//int b = 31.3;
double c = 2;
double d = 12.4;
print(a/c);
// + - * /
Strings(字符串)
String
var str = 'str1';
String str2 = 'str2';
String str3 = '''
dddddddd
ffff
gggg
''';
String str4 = """
44444444
ssssss
""";
print(str);
print(str2);
print(str3);
print(str4);
print('$str $str2');
print(str + ' ' +str2);
Booleans(布尔)
bool
bool flag = true;
bool flag2 = false;
print(flag == flag2);
List(数组)
在Dart中,数组是列表对象,所以大多数人只是称它们为列表
var l1 = [1,'a',true];
List l2 = <String>['a','b'];
List l3 = <int>[1,3,4];
List l4 = [];
l4.add('a');
l4.addAll(['b','c','d']);
print(l1);
print(l2);
print(l3);
print(l4);
//通过List.filled创建的集合长度是固定
var l6 = List.filled(2, "");
// l6.add('c');
l6[0] = 'a';
print(l6);
print(l6.length);
// l6.length=0; //修改集合的长度 报错
Maps(字典)
通常来说,Map 是一个键值对相关的对象。 键和值可以是任何类型的对象。每个 键 只出现一次, 而一个值则可以出现多次
//第一种定义 Maps的方式
// var person={
// "name":"张三",
// "age":20,
// "work":["程序员","送外卖"]
// };
// print(person);
// print(person["name"]);
// print(person["age"]);
// print(person["work"]);
//第二种定义 Maps的方式
var p=new Map();
p["name"]="李四";
p["age"]=22;
p["work"]=["程序员","送外卖"];
print(p);
print(p["age"]);
类型判断
通过is关键字判断类型
var str = 13;
if (str is String) {
print('是string类型');
} else if (str is int) {
print('int');
} else {
print('其他类型');
}
Dart运算符
1、Dart运算符:
算术运算符
+ - * / ~/ (取整) %(取余)
关系运算符
== != > < >= <=
逻辑运算符
&& || !
赋值运算符
基础赋值运算符 = ??=
// b??=23; 表示如果b为空的话把 23赋值给b
var b;
b??=23;
print(b);
// var b = 5;
// b??=23;
// print(b);
复合赋值运算符 += -= *= /= %= ~/=
条件表达式
if else switch case
三目运算符
??运算符:
??运算符
var a;
var b= a ?? 10;
print(b);
// var a=22;
// var b= a ?? 10;
// print(b);
2、类型转换
1、Number与String类型之间的转换
Number类型转换成String类型 toString()
String类型转成Number类型 int.parse()
String str='123';code>
var myNum=int.parse(str);
print(myNum is int);
// String str='123.1';code>
// var myNum=double.parse(str);
// print(myNum is double);
// var myNum=12;
// var str=myNum.toString();
// print(str is String);
2、其他类型转换成Booleans类型
判断是否为空 isEmpty
// isEmpty:判断字符串是否为空
var str = '';
if (str.isEmpty) {
print('str空');
} else {
print('str不为空');
}
var myNum;
print (myNum == 0); //false
print (myNum ==null); // true
Dart循环
for循环
for (int i = 1; i<=10; i++) {
if(i%2 == 0){
print('$i 偶数');
};
print(i);
}
while循环
int i=1;
while(i<=10){
print(i);
i++;
}
do...while循环
int i = 10;
do{
print(i);
}while(i<=8);
跳出循环
break语句功能:
1、在switch语句中使流程跳出switch结构。
2、在循环语句中使流程跳出当前循环,遇到break 循环终止,后面代码也不会执行
强调:
1、如果在循环中已经执行了break语句,就不会执行循环体中位于break后的语句。
2、在多层循环中,一个break语句只能向外跳出一层
break可以用在switch case中 也可以用在 for 循环和 while循环中
for (var i = 1; i <= 10; i++) {
if (i == 4) {
break; /*跳出循环体*/
}
print(i);
}
continue语句的功能:
【注】只能在循环语句中使用,使本次循环结束,即跳过循环体重下面尚未执行的语句,接着进行下次的是否执行循环的判断。
continue可以用在for循环以及 while循环中,但是不建议用在while循环中,不小心容易死循环
for(var i=1;i<=10;i++){
if(i==4){
continue; /*跳过当前循环体 然后循环还会继续执行*/
}
print(i);
}
List
List里面常用的属性和方法:
常用属性:
length 长度
reversed 翻转
isEmpty 是否为空
isNotEmpty 是否不为空
List myList=['香蕉','苹果','西瓜'];
print(myList.length);
print(myList.isEmpty);
print(myList.isNotEmpty);
print(myList.reversed); //对列表倒序排序
var newMyList=myList.reversed.toList();
print(newMyList);
常用方法:
add 增加
addAll 拼接数组
indexOf 查找 传入具体值
remove 删除 传入具体值
removeAt 删除 传入索引值
fillRange(start,end,ele) 修改
List myList=['香蕉','苹果','西瓜'];
myList.fillRange(1, 2,'aaa'); //索引起始位置,结束位置,修改信息
print(myList);
insert(index,value); 指定位置插入
insertAll(index,list) 指定位置插入List
List myList=['香蕉','苹果','西瓜'];
myList.insert(1,'aaa'); //插入 一个
myList.insertAll(1, ['bbb','ccc']); //插入 多个
print(myList);
toList() 其他类型转换成List
join() List转换成字符串
split() 字符串转化成List
forEach
map
where
any
every
Set
主要的功能就是去除数组重复内容
Set是没有顺序且不能重复的集合,所以不能通过索引去获取值
List myList=['香蕉','苹果','西瓜','香蕉','苹果','香蕉','苹果'];
var s=new Set();
s.addAll(myList);
print(s);
print(s.toList());
Map
映射(Maps)是无序的键值对:
常用属性:
keys 获取所有的key值
values 获取所有的value值
isEmpty 是否为空
isNotEmpty 是否不为空
Map person={
"name":"张三",
"age":20,
"sex":"男"
};
print(person.keys.toList());
print(person.values.toList());
print(person.isEmpty);
print(person.isNotEmpty);
常用方法:
remove(key) 删除指定key的数据
addAll({...}) 合并映射 给映射内增加属性
containsValue 查看映射内的值 返回true/false
Map person={
"name":"张三",
"age":20,
"sex":"男"
};
// person.addAll({
// "work":['敲代码','送外卖'],
// "height":160
// });
// print(person);
// person.remove("sex");
// print(person);
print(person.containsValue('张三'));
常用方法
forEach
List myList = ['a','b','c'];
myList.forEach((value){
print("$value");
});
map
List myList=[1,3,4];
var newList=myList.map((value){
return value*2;
});
print(newList.toList());
where
返回满足条件的列表
List myList=[1,3,4,5,7,8,9];
var newList=myList.where((value){
return value>5;
});
print(newList.toList());
any
有任意一项满足条件即返回true
List myList=[1,3,4,5,7,8,9];
var f=myList.any((value){ //只要集合里面有满足条件的就返回true
return value>5;
});
print(f); //true
every
每一个都满足条件返回true 否则返回false
List myList=[1,3,4,5,7,8,9];
var f=myList.every((value){ //只要集合里面有满足条件的就返回true
return value>5;
});
print(f);//false
Dart方法
内置方法/函数:
print();
自定义方法:
自定义方法的基本格式
返回类型 方法名称(参数1,参数2,...){
方法体
return 返回值;
}
void printInfo(){
print('自定义方法');
}
printInfo();
携带参数
int 方法(int 参数){};
规定返回值是int类型 传入参数int类型
int sumNum(int n){
var sum=0;
for(var i=1;i<=n;i++)
{
sum+=i;
}
return sum;
}
print(sumNum(10));
可选参数
String printUserInfo(String username,[int age=0]){};
String printUserInfo(String username,[int age=0]){ //行参
if(age!=0){
return "姓名:$username---年龄:$age";
}
return "姓名:$username---年龄保密";
}
print(printUserInfo('张三',21)); //实参
print(printUserInfo('张三'));
默认参数
String printUserInfo(String username,[String sex='男',int age=0]){ //行参code>
if(age!=0){
return "姓名:$username---性别:$sex--年龄:$age";
}
return "姓名:$username---性别:$sex--年龄保密";
}
print(printUserInfo('张三'));
print(printUserInfo('小李','女'));
print(printUserInfo('小李','女',30));
命名参数
定义一个命名参数的方法,最新的dart定义命名参数需要指定类型默认值
String printUserInfo(String username, {int age = 0, String sex = '男'}) {
if (age != 0) {
return "姓名:$username---性别:$sex--年龄:$age";
}
return "姓名:$username---性别:$sex--年龄保密";
}
print(printUserInfo('张三', age: 20, sex: '未知'));
// print(printUserInfo('张三', age: 20,'女'));
将函数作为参数
fn1() {
print('fn1');
}
//fn2方法
fn2(fn) {
fn();
}
fn2(fn1);
箭头函数
注意和方法的区别: 箭头函数内只能写一条语句,并且语句后面没有分号(;)
List list=['苹果','香蕉','西瓜'];
list.forEach((value)=>
{
print(value)
});
匿名函数
var printNum=(){
print(123);
};
printNum();
自执行方法
((int n){
print(n);
print('自执行方法');
})(12);
闭包
1、全局变量特点: 全局变量常驻内存、全局变量污染全局
2、局部变量的特点: 不常驻内存会被垃圾机制回收、不会污染全局
fn() {
var a = 123; /*不会污染全局 常驻内存*/
return () {
a++;
print(a);
};
}
var b = fn();
b();
b();
b();
Dart面向对象
面向对象编程(OOP)的三个基本特征是:封装、继承、多态
1. 封装:封装是对象和类概念的主要特性。封装,把客观事物封装成抽象的类,并且把自己的部分属性和方法提供给其他对象调用, 而一部分属性和方法则隐藏。
2. 继承:面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
3. 多态:允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果
Dart所有的东西都是对象,所有的对象都继承自Object类。
Dart是一门使用类和单继承的面向对象语言,所有的对象都是类的实例,并且所有的类都是Object的子类。
一个类通常由属性和方法组成。
class Person {
String name = "张三";
int age = 23;
void getInfo() {
// print("$name----$age");
print("${this.name}----${this.age}");
}
void setInfo(int age) {
this.age = age;
}
}
void main() {
Person p1 = new Person();
print(p1.name);
p1.setInfo(6);
p1.getInfo();
}
Dart类的默认构造函数
//最新版本的dart中需要初始化不可为null的实例字段,如果不初始化的话需要在属性前面加上late
// class Person{
// late String name;
// late int age;
// //默认构造函数
// Person(String name,int age){
// this.name=name;
// this.age=age;
// }
// void printInfo(){
// print("${this.name}----${this.age}");
// }
// }
class Person{
late String name;
late int age;
//默认构造函数的简写
Person(this.name,this.age);
void printInfo(){
print("${this.name}----${this.age}");
}
}
void main(){
Person p = new Person('张三',20);
Person p2 = new Person('李四',30);
print(p.age);
p2.printInfo();
}
命名构造函数
class Person {
late String name;
late int age;
//默认构造函数的简写
Person(this.name, this.age);
Person.now() {
print('我是命名构造函数');
}
Person.setInfo(String name, int age) {
this.name = name;
this.age = age;
}
void printInfo() {
print("${this.name}----${this.age}");
}
}
void main(){
var d=new DateTime.now(); //实例化DateTime调用它的命名构造函数
print(d);
Person p = new Person.now();
}
私有属性和方法
Dart和其他面向对象语言不一样,Data中没有 public private protected这些访问修饰符合
可以使用 "_" 把一个属性或者方法定义成私有。
class Animal{
late String _name; //私有属性
late int age;
//默认构造函数的简写
Animal(this._name,this.age);
void printInfo(){
print("${this._name}----${this.age}");
}
String getName(){
return this._name;
}
void _run(){
print('这是一个私有方法');
}
execRun(){
this._run(); //类里面方法的相互调用
}
}
void main(){
Animal a = new Animal('小狗',3);
a.execRun();
}
get set
class Rect{
late num height;
late num width;
Rect(this.height,this.width);
get area{
return this.height*this.width;
}
set areaHeight(value){
this.height=value;
}
}
void main() {
Rect a = new Rect(10, 2);
print(a.area);
a.areaHeight = 20;
print(a.area);
}
初始化列表
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(r.getArea());
}
Dart静态成员
1、使用static 关键字来实现类级别的变量和函数
class Person {
static String name = '张三';
static void show() {
print(name);
}
}
main(){
print(Person.name);
Person.show();
}
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(); //静态方法
//print(this.age); //静态方法没法访问非静态的属性
// this.printInfo(); //静态方法没法访问非静态的方法
// printInfo();
}
}
main() {
// print(Person.name);
// Person.show();
Person p=new Person();
p.printInfo();
// Person.printUserInfo();
}
Dart中的对象操作符
? 条件运算符 (了解)
Person p;
p?.printInfo(); //已被最新的dart废弃 了解
as 类型转换
class Person {
String name;
num age;
Person(this.name, this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
main() {
var p1;
p1='';code>
p1=new Person('张三1', 20);
(p1 as Person).printInfo();
}
is 类型判断
class Person {
String name;
num age;
Person(this.name, this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
main() {
Person p=new Person('张三', 20);
if(p is Person){
p.name="李四";code>
}
p.printInfo();
}
.. 级联操作 (连缀)
class Person {
String name;
num age;
Person(this.name, this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
main() {
Person p1 = new Person('张三1', 20);
p1.printInfo();
p1
..name = "李四"
..age = 30
..printInfo();
}
Dart中的类的继承
1、子类使用extends关键词来继承父类
2、子类会继承父类里面可见的属性和方法 但是不会继承构造函数
3、子类能复写父类的方法 getter和setter
extends继承
class Person {
String name='张三';code>
num age=20;
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Web extends Person{
}
main(){
Web w=new Web();
print(w.name);
w.printInfo();
}
super关键字
class 子类 extends 父类{
子类(类型 变量,类型 变量) :super(变量,变量){
}
}
class Person {
late String name;
late num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Web extends Person{
Web(String name, num age) : super(name, age){
}
}
main(){
Web w=new Web('张三', 12);
w.printInfo();
}
class Person {
late String name;
late num age;
Person(this.name, this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Web extends Person {
late String sex;
Web(String name, num age, String sex) : super(name, age) {
this.sex=sex;
}
}
main() {
Web w = new Web('张三', 12, '男');
w.printInfo();
print(w.sex);
}
覆写父类方法
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
work(){
print("${this.name}在工作...");
}
}
class Web extends Person{
Web(String name, num age) : super(name, age);
run(){
print('run');
}
//覆写父类的方法
@override //可以写也可以不写 建议在覆写父类方法的时候加上 @override
void printInfo(){
print("姓名:${this.name}---年龄:${this.age}");
}
@override
work(){
print("${this.name}的工作是写代码");
}
}
main(){
Web w=new Web('李四',20);
w.run();
w.printInfo();
w.work();
}
子类调用父类方法
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
work(){
print("${this.name}在工作...");
}
}
class Web extends Person{
Web(String name, num age) : super(name, age);
run(){
print('run');
super.work(); //子类调用父类的方法
}
}
main(){
Web w=new Web('李四',20);
// w.printInfo();
w.run();
}
Dart中的抽象类
Dart抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。
1、抽象类通过abstract 关键字来定义
2、Dart中的抽象方法不能用abstract声明,Dart中没有方法体的方法我们称为抽象方法。
3、如果子类继承抽象类必须得实现里面的抽象方法
4、如果把抽象类当做接口实现的话必须得实现抽象类里面定义的所有属性和方法。
5、抽象类不能被实例化,只有继承它的子类可以
abstract抽象类
abstract class Animal{
eat(); //抽象方法
run(); //抽象方法
printInfo(){
print('我是一个抽象类里面的普通方法');
}
}
class Dog extends Animal{
@override
eat() {
print('小狗在吃骨头');
}
@override
run() {
print('小狗在跑');
}
}
class Cat extends Animal{
@override
eat() {
print('小猫在吃鱼');
}
@override
run() {
print('小猫在跑');
}
}
main(){
Dog d=new Dog();
d.eat();
d.printInfo();
Cat c=new Cat();
c.eat();
c.printInfo();
//Animal a=new Animal(); //抽象类没法直接被实例化
}
implements定义接口
abstract class Db{
late String uri;
add(String data);
save();
delete();
}
class Mysql implements Db{
@override
String uri;
Mysql(this.uri);
@override
add(data) {
print('这是mysql的add方法'+data);
}
@override
delete() {
return null;
}
@override
save() {
return null;
}
// 子类方法
remove(){
}
}
class MsSql implements Db{
@override
late String uri;
@override
add(String data) {
print('这是mssql的add方法'+data);
}
@override
delete() {
return null;
}
@override
save() {
return null;
}
}
main() {
Mysql mysql=new Mysql('xxxxxx');
mysql.add('1243214');
}
extends抽象类 和 implements的区别:
1、如果要复用抽象类里面的方法,并且要用抽象方法约束子类的话我们就用extends继承抽象类
2、如果只是把抽象类当做标准的话我们就用implements实现抽象类
implements一个类实现多个接口
子类C implements 父类A,父类B{}
abstract class A{
late String name;
printA();
}
abstract class B{
printB();
}
class C implements A,B{
@override
late String name;
@override
printA() {
print('printA');
}
@override
printB() {
return null;
}
}
void main(){
C c=new C();
c.printA();
}
mixins混入
在Dart中可以使用mixins实现类似多继承的功能
在 dart 3.0.0 之后, mixin 变严格了,和 class 声明的常规类进行的区分,常规类将不被允许混入
mixin 声明定义了一个混入类,允许被通过 with 混入或 on 继承。
class 声明定义了一个常规类,允许被通过 extends 继承。
mixin class 声明定义了一个既可用作常规类又可用作混入类的类。即允许被通过 with 混入或 on 继承,又允许被通过 extends 继承。
// class A {
// String info="this is A";code>
// void printA(){
// print("A");
// }
// }
// class B {
// void printB(){
// print("B");
// }
// }
// class C with A,B{
// }
mixin A {
String info="this is A";code>
void printA(){
print("A");
}
}
mixin B {
void printB(){
print("B");
}
}
class C with A,B{
}
void main(){
var c=new C();
c.printA();
c.printB();
print(c.info);
}
extends和mixin使用
在不同父类中有同名方法,继承最后一个父类方法
class Person{
String name;
num age;
Person(this.name,this.age);
printInfo(){
print('${this.name}----${this.age}');
}
void run(){
print("Person Run");
}
}
mixin A {
String info="this is A";code>
void printA(){
print("A");
}
void run(){
print("A Run");
}
}
mixin B {
void printB(){
print("B");
}
void run(){
print("B Run");
}
}
class C extends Person with B,A{
C(String name, num age) : super(name, age);
}
void main(){
var c=new C('张三',20);
c.printInfo();
// c.printB();
// print(c.info);
c.run();
}
Dart泛型
泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)
//只能返回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;
}
泛型写法
T getData<T>(T value){
return value;
}
void main(){
print(getData<int>(12));
}
泛型类
abstract class Cache<T> {
getByKey(String key);
void setByKey(String key, T value);
}
class FileCache<T> implements Cache<T> {
@override
getByKey(String key) {
return null;
}
@override
void setByKey(String key, T value) {
print("我是文件缓存 把key=${key} value=${value}的数据写入到了文件中");
}
}
class MemoryCache<T> implements Cache<T> {
@override
getByKey(String key) {
return null;
}
@override
void setByKey(String key, T value) {
print("我是内存缓存 把key=${key} value=${value} -写入到了内存中");
}
}
void main() {
FileCache f=new FileCache<String>();
f.setByKey('index', '首页数据');
MemoryCache m = new MemoryCache<Map>();
m.setByKey('index', {"name": "张三", "age": 20});
}
上一篇: Vue3使用动态组件 Component
下一篇: SpringBootWeb 篇-深入了解会话技术与会话跟踪三种技术(Cookie 会话跟踪、Session 会话跟踪与 JWT 令牌会话跟踪)
本文标签
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。