Flutter之Dart基础从零学原创
原创加粗样式
提示:本文是一篇前端学习文章flutter过程中,如果有歧义,希望大家有很大的宝贵意见。
文章目录
-
- 1.声明一个返回值为空的条目文件。
- 2.Dart变量的声明和使用。
- 3.Dart命名规则
- 4.Dart 常量
- 5.Dart 数据类型
- 6.Dart 运算符 条件判断 类型转换
- 7.Dart 中的遍历for while 和do while break continue
- 8.Dart 函数、定制函数、可选参数、默认参数、命名参数、箭头函数、匿名函数、闭包等。
- 9.Dart 中的类 对象
- 10.Dart中的类 静态成员 操作符 类的继承
- 11.Dart中 抽象类 多态 和接口
- 12 mixins混搭功能的使用!mixins与继承一起使用!
- 13. 泛型类 泛型方法 泛型接口 泛型mixins 的使用
- 14 Dart 中的库 自定义库 系统库 第三方库
- 15.Dart 2.13以下是一些新功能 Null safety、late 关键字,空类型声明符?,非空断言!,required 关键字;
-
- *
前言
提示:想学好吗?flutter你需要先学习数字。Dart;
·flutter 安装流程·
1.什么是Dart?
提示:以下是本文的主体部分。以下案例具有一定的借鉴意义。
1.了解Dart
Dart官方文件: 链接地址
Dart For Windows: 下载地址
2.安装Dart(windows)mac自行安装;
1.下载 下载地址 傻傻的,一步一步安装,等待
2.检查安装是否成功‘cmd’ 中输入
dart --version
安装成功
3.开发工具 vscode 插件安装
1.下载 vscode: 下载地址
2.安装vscode软件
3.给vscode安装dart插件
在开发工具中选择向左箭头,然后输入向上箭头。 dart 和 code runner
4.运行我的第一个dart文件
文件命名需要基于.dart结束;例如:index.dart
main() { // 入口文件
print(hello dart...);
}
二、Dart使用
1.声明一个返回值为空的条目文件。
代码如下(示例):
void main() { // void 表示返回值为空
print(hello dart...);
}
2.Dart变量的声明和使用。
1.使用var 定义的变量 可以自己压低自己的类型;
2.使用 数据类型定义的变量不能推送,只能是定义的类型;
代码如下(示例):
void main() {
var str = zhangsan; // 它会自动往下推到这里。str是字符串类型
// str = 123 // 如果给str为其他数据类型赋值将导致错误。
print(str);
String str2 = lisi; // 定义字符串类型的变量
// str2 = 10 // 如果给str2赋值其他数据类型的值(数字),则会出现错误
print(str2);
}
注意:如果确定了变量类型,并将另一种类型的值赋给了该变量,则会出现错误,如上图所示。~
3.Dart命名规则
4.Dart 常量
void main(){
// 这只能在这里使用。final start
final a = new DateTime.now();
// const b = new DateTime.now(); // 错误的书写,可以在这里使用。final
print(a);
// 这只能在这里使用。final end
// 此方法使用final和const结果是一样的 start
final c = 3.14159;
const d = 3.14159;
print(c);
print(d);
// 此方法使用final和const结果是一样的 end
}
注意:常量不能修改~
5.Dart 数据类型
5.1.定义字符串String和var和串绕效果
var str1 = 这是一个字符串;
String str2 = 这也是一个字符串;
print(str1);
print(str2);
var str3 =
这是换行符
这是换行符
这是换行符
;
print(str3); // 字符串换行 支持单引号和双引号
注:可以使用String和var定义 ;‘’’ 该字符串可识别换行符。 ‘’’
5.2.定义数值类型int 和double
int a = 22;
a = 43; // int定义的变量赋值必须为int,否则上报错误;
print(a);
double b = 34.33;
b = 30; // double定义的变量赋值可以是int 也可以是double所有都支持赋值,整数被转换30.0
print(b);
注意:int定义的变量赋值必须为int,否则上报错误;double定义的变量赋值可以是int 也可以是double所有都支持赋值,整数被转换30.0
5.3.定义布尔类型bool
bool flag = true;
var flay = true;
print(flay);
print(flag);
if (flay == flag) {
print(成功了);
} else {
print(失败..);
}
5.4.定义List打字四种方式
// 第一个定义List的方式 未指定类型
var list = [1, 2, 颤三1]; // list中的所有值可以是任何类型;var 可以换成List
print(list);
list.length = 0;
print(list);
// 第二个定义List的方式 指定类型
var list2 = [颤三2, 李四2, 王五2]; // 指定list中的所有值必须为字符串类型;var 可以换成List
print(list2);
// 第三个定义List的方式 增加数据,[]创建的集合变量的能力可以改变,即可以改变;
var list3 = []; // 无论这里有没有缺省值,都是可以的。add增加的
list3.add(张三3);
list3.add(李四3);
list3.add(王五3);
print(list3);
// 第四个定义List的方式
// var lists4 = new List(); // 此方法是最新版本。dart新版本不能再使用,也不推荐使用;
// 创建定长收藏只能定义,不能增加或减少;
var lists5 = List.filled(2, ); // var 可以换成List
print(lists5);
print(lists5.length);
print(list5[0] = + lists5[0]);
print(list5[1] = + lists5[1]);
lists5[0] = 颤三5;
lists5[1] = 李四5;
print(lists5);
print(lists5.length);
// lists5.add(王五); // 这里会上报错误,因为长度是固定的,不能添加;
// lists5.length = 0 ; // 这里会报告错误,因为长度是固定的,不能减少;
var list6 = List.filled(3, ); // 指定的长度指定数组的每个值的类型;var 可以换成List
注意:跟js中的array 相同;在样本中var 可以换成List 定义变量;
5.5.List 常见属性和方法
1.常用属性
length 长度
reversed 翻转
isEmpty 是否为空
isNotEmpty 它不是空的吗?
List lists = [1, 10, 3, 6];
print(lists.length); // 结果4
print(lists.reversed); // (6,3,10,1)
print(lists.reversed.toList()); // [6, 3, 10, 1]
print(lists.isEmpty); // false
print(lists.isNotEmpty); // true
2.常用方法
add(值) 添加数据 添加一个
addAll(数组) 拼接数组
indexOf(值) 查找数据
返回值:数组下标返回成功,返回失败-1;
remove(值) 删除 传入特定值
返回值:true或false,表示删除成功或失败;
removeAt(下标) 删除 传入索引值
返回值:删除的值
fillRange(开始下标,结束下标,修改的值) 修改 必须传递传入的开始和结束索引值 和 修改值
insert(下标,值) 插入 下标和值
insertAll(下标,数组) 插入 下标和数组
join(-) 和split(-)用法与js一致
toList() 和var set = new Set() // 删除重复数据
set.addAll([数组]);获取对象,然后.toList();转换为数组;
List myList = [香蕉, 苹果, 李子, 香蕉];
// myList.add(橘子); // 新增数据 增加一个
// print(myList);
// myList.addAll([桃子, 西瓜]); // 拼接数组 增加多个
// print(myList);
// print(myList.indexOf(香蕉)); // 查找数据,成功返回数组索引值,返回失败-1;重复数据,命令从左到右删除第一个找到的数据。
// print(myList.remove(香1蕉)); // 删除数据,从左到右只删除第一个找到的数据。
// print(myList);
// print(myList.removeAt(0)); // 删除数据,从左到右只删除第一个找到的数据。
// print(myList);
// myList.fillRange(1, 2, 新苹果); // 从1开始到2结尾不带下标2
// myList.insert(0, 小香蕉); // 插入数据
// myList.insertAll(0, [小苹果, 小西瓜]); // 插入多条数据
// String str = myList.join(,); // 转换为字符串
// print(str);
// print(str.split(,)); // 转成数组
// set 去重复法 及tolist方法的使用;
// var set = new Set();
// set.addAll(myList);
// print(set); // 取消重复后显示对象。 {香蕉, 苹果, 李子}
// print(set.toList()); // 对象到数组
print(myList);
5.6.定义Maps类型
// 1.第一个定义Maps的方式
var person = {"name": "张三", "age": 12}; // 此处的var 可以换成Map 还可以定义
print(person[name]);
// 2.第一个定义Maps的方式
var person2 = new Map();
person2[name] = 颤三2;
person2[age] = 11;
print(person2[name]);
print(person2[age]);
注意:跟js中json这些对象有些一致;同样dart中定义maps key 必须用引号引起来;person[‘name’]
5.7.Maps常见属性和方法
1.常用属性
keys 包揽所有key值
values 包揽所有value值
isEmpty 是否为空
isNotEmpty 它不是空的吗?
var person = {"name": 颤三, "age": 20};
print(person.keys.toList());
print(person.values.toList());
print(person.isEmpty);
print(person.isNotEmpty);
2.常用方法
addAll({ ...}) 合并映射 将新属性添加到映射
remove(key) 删除指定key的数据
containsValue 查看地图中的值。
var person = {"name": 颤三, "age": 20};
person.addAll({"weight": 150, "height": 160});
print(person);
person.remove(weight);
print(person);
print(person.containsValue(颤三)); // 返回值为true和false;
5.8.Map List 公共循环语句 forEach map where any every 详解;
数组使用
// // forEach 逐一展示
// persons.forEach((item) {
// print(item);
// });
// // map 需要配合return通过生成一个字符串。toList()转换为数组
// var newPersons = persons.map((item) {
// return item;
// });
// print(newPersons.toList());
// // where 需要配合return通过生成一个字符串。toList()转换为数组
// var newPersons = persons.where((item) {
// return item == 张三;
// });
// print(newPersons.toList());
// // any 需要配合return使用时,任何复合条件都会返回bool
// var newPersons = persons.any((item) {
// return item == 张三;
// });
// print(newPersons);
// // 简写
// var newPersons = persons.any((item) => item == 张三);
// print(newPersons);
// every 需要配合return使用,则任何符合条件的都会返回一个bool,与any正好想法
// var newPersons = persons.every((item) {
// return item == 张三;
// });
// print(newPersons);
// // 简写
// var newPersons = persons.every((item) => item == 张三);
// print(newPersons);
map使用
person.forEach((key, value) {
print("$key --- $value");
});
注意:map使用遍历和list区别在于,map有两个参数,key和value ,list只有一个参数value;
5.9.is判断Dart数据类型
var str = aimee;
if (str is String) { // 有些编辑会有波浪线提示,请忽略,这是为了反映is的用法
print(str 是string类型);
} else if (str is int) {
print(str 是int类型);
} else {
print(其他类型);
}
6.Dart 运算符 条件判断 类型转换
6.1.Dart运算符
1.算术运算符 “ + - * % 求余 取整
”
var num1 = 13;
var num2 = 5;
print(num1 + num2); // 加
print(num1 - num2); // 减
print(num1 * num2); // 乘
print(num1 / num2); // 除
print(num1 % num2); // 求余
print(num1 ~/ num2); // 取整
2.关系运算符 " == (等于) !=(不等于) >(大于) >=(大于或等于) <(小于) <=(小于或等于)
`"
var num1 = 13;
var num2 = 5;
print(num1 > num2); // 大于
print(num1 < num2); // 小于
print(num1 >= num2); // 大于等于
print(num1 <= num2); // 小于等于
print(num1 == num2); // 等于
print(num1 != num2); // 不等于
3.逻辑运算符 “ !(取反) &&(并且) ||(或者)
” 与js没有详细给出一致的用法;
4.赋值操作符 “ = (等于) ??=(如果值为空,则赋值。=在右侧,如果不为空,则不会被赋值)
”
4.1 ‘ = ’ 执行任务的顺序是从右到左,先计算后分配;
4.2 var b; b??=23; // 结果为23 , b如果为空,则赋值为23
var b =10; b??=23; // 结果为10 , b如果不为空,则取该值。10
5.复合赋值操作符
var a = 20;
a += 10; // 复合赋值加法 a=a+10
a -= 10; // 复合赋值减法 a=a-10
a *= 10; // 复合赋值乘法 a=a*10
// a /= 2; // 复合分配除法 a=a/10 // 这里报告了一个错误,无法理解。
a %= 10; // 余数的复合赋值 a=a%10
a ~/= 10; // 复合分配取证 a=a~/10
-
"
++ --
" 在赋值操作中,++在此之后,在计算之前赋值,++前面是作业中的第一个计算;var a = 10; var b = a++; // a++意思就是a = a+1; ++在后面就是先给b分配重新计算,++前面是作业中的第一个计算。b;
6.2.Dart条件判断
1.if else switch case //跟js一种用法;
2.三木操作员 //跟js一种用法;
3.??运算符 //跟上面4.2一个意思 ,等待空虚??对于后者,如果不是空的,则使用原始的;
6.3.Dart类型转换
-
toString()
强制转换为字符串类型;var num = 123; var num1 = num.toString(); print(num1 is String);
-
int.parse() ;double.parse()
强制转换int和double类型;var num = 111; var num1 = int.parse(num); var num2 = double.parse(num); print(num1); print(num2); print(num1 is int); print(num2 is double);
-
isEmpty
和try catch的使用var price = 111; try { var myPrice = double.parse(price); print(myPrice); } catch (err) { print(0.0); }
var a = ; if (a.isEmpty) { print(a 是空的); } else { print(a 不是空的); } var b = 0/0; if(b.isNaN){ print(NaN ); }
7.Dart 中的遍历for while 和do while break continue
与js使用的方法是相同的。没有录音;我是从前端来的,所以这些仍然很熟悉。如果你对它们不熟悉,你可以自己去看看;
8.Dart 函数、定制函数、可选参数、默认参数、命名参数、箭头函数、匿名函数、闭包等。
8.1.自定义函数,自定义方法
自定义函数 在main函数的外部定义是一个全局函数,可以在任何地方使用;
在main该函数中定义的函数为main的范围函数main在函数内使用,不能超出范围使用;
如果自定义函数有返回值,则它必须具有return 使用;
可以编写不带返回值的自定义函数。void 您也可以直接编写函数名,而不需要编写任何内容;
自定义函数名称需要使用驼峰命名规则,第一个单词小写,下一个单词大写;
void main() {
/***
* 1**.定义返回值和不定义返回值的方法**
*/
void sayHello() {
// 定义不返回值的函数。
print(hello world);
}
String sayString() {
// 定义了返回值的函数
return hello string;
}
sayHello();
print(sayString());
/***
* 2.定义本地范围
* 在sayWord方法也可以定义为word方法,新定义的word方法只能在sayWord内使用
*/
sayWord() {
// word(); // 不能使用 我们必须先定义它,然后再使用它。 Error: Cant declare word because it was already used in this scope.
word() {
print(我的范围只能在。sayWord内部使用,超越错误报告!);
}
word(); // 能使用
}
sayWord();
// word();// 报告的错误超出范围 Error: Method not found: word
sayChina(); // 调用全局自定义方法;
}
/**
* 全局方法
*
*/
sayChina() {
print(你好 ,我的中国);
}
8.2.函数传递参数(必选参数)
void main() {
int sum(int b) { // int 指定接收到的参数的类型,并且必须是此类型
int count = 0;
for (var i = 1; i <= b; i++) {
count += i;
}
return count;
}
// print(sum(100)); // 报错 Error: The argument type String cant be assigned to the parameter type int.
print(sum(100)); // 必须传int类型
}
8.3.函数参数可选参数[int? age,String? sex]
void main() {
String sayUserInfo(String name, [int? age, String? sex]) {
// 规定必须具有name参数,参数age和参数sex是可选参数
String ageN = age != null ? (age.toString() + 岁) : 保密;
String sexN = age != null ? sex.toString() : 保密;
return "姓名:$name ----年龄:$ageN ----性别:$sexN";
}
print(sayUserInfo(张三)); // 姓名:张三 ----年龄:保密 ----性别:保密
print(sayUserInfo(张三, 12, girl)); //姓名:张三 ----年龄:12岁 ---性别:girl
}
8.4.函数传递参数(默认参数)[String? sex = ‘boy’])
String sayUserInfo(String name, [int? age, String? sex = boy]) {
// 规定必须具有name参数,参数age和参数sex是可选参数
String ageN = age != null && age > 0 ? (age.toString() + 岁) : 保密;
String sexN = sex == gril || sex == boy ? sex.toString() : 保密;
return "姓名:$name ----年龄:$ageN ----性别:$sexN";
}
print(sayUserInfo(张三)); //姓名:张三 ----年龄:保密 ----性别:boy
print(sayUserInfo(张三, 22, begoy)); // 姓名:张三 ----年龄:22岁 ----性别:保密
8.5.函数传递参数(命名参数)
void main() {
String checkInfo(String name, {int? age, String? sex = 男}) {
String tips = ;
if (age == null) {
tips = "姓名:$name,年龄:保密,性别:$sex";
return tips;
}
tips = "姓名:$name,年龄:$age,性别:$sex";
return tips;
}
print(checkInfo(颤三, age: 22, sex: 男));
print(checkInfo(颤三, sex: 女));
print(checkInfo(颤三, age: 22));
print(checkInfo(颤三));
}
8.6.将该方法作为参数。
void main() {
void sayHello() {
print(我跟你打招呼);
}
void person(xingcan) { // 形参
xingcan(); // 调用形参
}
person(sayHello); // 将函数作为参数发送
}
8.7.箭头函数、匿名方法、自执行方法;
箭头函数
alist.forEach((item) => item % 2 == 0 ? item * 2 : item)
alist.forEach((item) => {
retun item % 2 == 0 ? item * 2 : item
})
匿名函数
var hello = (String name) {
print($name say hello);
};
hello(zzc);
自动执行功能 ;它在没有被称为自身的情况下执行;
(() {
print(hello);
})();
方法的递归 注:记住要注意return 或者在一个循环中死去;
var sum = 0;
add(int n) {
sum = sum + n;
if (n == 1) {
print(sum);
return;
}
add(n - 1);
}
add(100);
9.Dart 中的类 对象
9.1.Dart 面向对象编程(oop3)三个基本特征:继承性、封装性、多态;
9.2.Dart 自定义类
// 声明一个类
class Person {
// 定义变量
String name = 张三;
int age = 22;
// 定义类的方法
getInfo() {
print("姓名:${this.name} --------- 年龄:${this.age}");
}
setInfo(String name, {int age = 18}) {
this.name = name;
this.age = age;
}
}
void main() {
// 实例化类的两种方法
var person = new Person();
Person person1 = new Person();
person1.getInfo();
person.setInfo(王五, age: 30);
person.getInfo();
}
9.3.Dart对类的构造函数的理解
默认构造函数(与类中的类同名的方法称为构造方法。),实例化时需要传递参数; 默认构造函数只能编写一个;
// 声明一个类
class Person {
// 定义变量
String name = ;
int age = 0;
// 默认构造函数(与类名相同的方法称为构造方法。)
// Person(String name, int age) {
// print(创建person该实例被触发。);
// this.name = name;
// this.age = age;
// }
// 默认构造函数速记
Person(this.name, this.age);
// 定义类的方法
void getInfo() {
print("姓名:${this.name} --------- 年龄:${this.age}");
}
}
void main() {
Person person = new Person(zhangsan, 20);
person.getInfo();
Person person1 = new Person(zhangsan1, 29);
person1.getInfo();
}
9.4.Dart类的命名构造函数。。
命名的提前遍历函数可以有多个
使用方法:Perso.now();这个now被命名为构造函数;
// 声明一个类
class Person {
// 定义变量
String name = ;
int age = 0;
// 默认构造函数 唯一
Person(this.name, this.age);
// 命名构造函数 可以多个
Person.setInfo(String name, int age) {
this.name = name;
this.age = age;
}
Person.addUserAge(String name, int age) {
this.name = name;
this.age = age + 10;
}
// 定义类的方法
void getInfo() {
print("姓名:${this.name} --------- 年龄:${this.age}");
}
}
void main() {
Person person = new Person.setInfo(王五, 30);
person.getInfo();
var person2 = new Person.addUserAge(LISI, 44);
person2.getInfo();
}
9.5.Dart 解压缩包被打包到一个单独的类中,以便于库的管理和重命名。,部分引进和储存
import lib/person.dart as lib; // 重命名库 “
import lib/person.dart show getInfo; // 只介绍了库。getInfo方法;
import lib/person.dart hide getInfo; // 只有库中的才被隐藏。getInfo方法;
在根目录下创建lib文件夹,在该文件夹下创建一个person.dart把整个person类放在这里
class Person {
// 定义变量
String name = ;
int age = 0;
// 默认构造函数 唯一
Person(this.name, this.age);
// 命名构造函数 可以多个
Person.setInfo(String name, int age) {
this.name = name;
this.age = age;
}
Person.addUserAge(String name, int age) {
this.name = name;
this.age = age + 10;
}
// 定义类的方法
void getInfo() {
print("姓名:${this.name} --------- 年龄:${this.age}");
}
}
介绍了需要使用它的地方 import lib/person.dart;
介绍了需要使用它的地方 并重命名 import lib/person.dart as lib;
import lib/person.dart;
//import lib/person.dart as lib; // 重命名库
//import lib/person.dart show getInfo; // 只介绍了库。getInfo方法;
//import lib/person.dart hide getInfo; // 只有库中的才被隐藏。getInfo方法;
void main() {
Person person = new Person.setInfo(王五, 30);
person.getInfo();
var person2 = new Person.addUserAge(LISI, 44);
person2.getInfo();
lib.Person p2 = new lib.Person(王三,20); //重命名后使用自定义库。
p2.getInfo();
}
9.6. Dart 需要使用类的私有属性和私有方法。_进行定义
类不会退出 _属性或方法失败,或可以访问;
class Animals {
String _name = ;
int age = 0;
Animals(this._name, this.age);
wang() {
print("${this._name}在叫 ${this.age}");
}
}
void main() {
Animals animal = new Animals(小狗, 22);
print(animal._name); // 如果类型和呼叫位于同一文件夹中,则可以访问它们。如果你拿出一个不同的文件夹,你将无法访问它;
animal.wang();
}
班级被取消了 _name只能在类内使用,相当于局部变量局部属性局部函数。
想访问_name或私有方法,则需要在要返回的类中声明一个中间方法。
1.抽离到/lib/animal.dart
class Animals {
String _name = ;
int age = 0;
Animals(this._name, this.age);
wang() {
print("${this._name}在叫 ${this.age}");
}
}
2.抽离到/lib/animal.dart
import lib/animal.dart;
void main() {
Animals animal = new Animals(小狗, 22);
// print(animal._name); // 如果类型和被叫方位于同一文件夹中,则可以访问它们。如果拉出不同的文件夹,则为该类的私有属性,无法访问;
animal.wang();
}
9.7.Dart中的get 和set 的使用
get和 set 与普通方法不同的是,没有(),普通方法有(),get 和 set 修改后的no()可以用作参数赋值。 this.name = sansan; print(this.name);get 和 set 可以用作方法,但不能用作()
class Reac {
int height = 0;
int width = 0;
Reac(this.height, this.width);
get area { // get 这样写
return this.height * this.width;
}
set setNewHeight(int height) { // set 这样写
this.height = height;
}
}
void main() {
var reac = new Reac(10, 10);
print(reac.area); // get这是调用
reac.setNewHeight = 4; // set 这样调用
print(reac.area);
}
10.Dart中的类 静态成员 操作符 类的继承
10.1.Dart(中的静态成员static) 修饰
1.使用static 定义静态属性和静态方法的关键字;
class Person {
static String name = 张三; // 静态属性
int age = 20; // 非静态属性
//静态方法
static void sayHello() {
print("静态方法 sayHello");
}
// 非静态方法
void sayWord() {
print("我是一个非静态的方法。");
}
}
2.静态方法不能访问非静态属性和方法,只能访问静态属性和静态方法;
class Person {
static String name = 张三; // 静态属性
int age = 20; // 非静态属性
//静态方法
static void sayHello() {
// 调用静态属性和静态方法。。
say();
print(静态方法调用同一类下的静态属性。name:${name});
// 调用非静态属性和方法。。 错误报告无法正常运行
// this.sayWord();
// print(静态方法调用同一类下的非静态属性。age:${this.age});
}
// 静态方法
static void say() {
print("我是一个静态方法,由静态方法调用。");
}
// 非静态方法
void sayWord() {
print("我是一个非静态的方法。");
}
}
void main() {
Person.sayHello();
}
3.非静态方法可以访问同一类(已移除)下的静态属性和方法。this直接使用),您还可以访问非静态属性和方法(推荐。this);
class Person {
static String name = 张三; // 静态属性
int age = 20; // 非静态属性
//静态方法
static void sayHello() {
print("静态方法 sayHello");
}
// 非静态方法
void say() {
print("我是一个非静态的方法。");
}
// 非静态方法 可以调用静态属性和方法 还可以调用非静态属性和方法。。。
void sayWord() {
print("我是一个非静态的方法。");
// 调用静态属性和静态方法。。
sayHello();
print(非静态方法调用同一类下的静态属性。。name:${name});
// 调用非静态属性和方法。。
print("非静态方法调用同一类下的非静态属性。。age:${this.age}");
this.say();
}
}
void main() {
// // 调用非静态属性
Person person = new Person();
print("调用非静态属性age:${person.age}"); // 调用非静态属性
person.sayWord(); //调用非静态方法sayWord
}
4.静态方法的调用 - > Person.name Person.show();
void main() {
// 调用静态属性
print(Person.name);
// 调用静态方法
Person.sayHello();
}
5.对非静态方法的调用 -> Person p = new Person();person.show();
void main() {
// 调用非静态属性
Person person = new Person();
print("调用非静态属性age:${person.age}"); // 调用非静态属性
person.sayWord(); //调用非静态方法sayWord
}
10.2 Dart中的对象运算符 ? as is ..
?
-------> 条件运算符(了解)
class Person {
String name = 张三;
int age = 20;
Person(this.name, this.age);
void showInfo() {
print(${this.name} ---------- ${this.age});
}
}
void main() {
var p;
p = new Person(小红, 11);
p?.showInfo(); // p 存在将呼唤showInfo方法
}
as
------> 类型转换
class Person {
String name = 张三;
int age = 20;
Person(this.name, this.age);
void showInfo() {
print(${this.name} ---------- ${this.age});
}
}
void main() {
var p;
p = ;
p = new Person(小明, 18);
(p as Person).showInfo(); // 强制转换Person类型
}
is
------> 类型判断
class Person {
String name = 张三;
int age = 20;
Person(this.name, this.age);
void showInfo() {
print(${this.name} ---------- ${this.age});
}
}
void main() {
Person person = new Person(张三, 22);
person.showInfo();
if (person is Person) {
print(person.is.new 1 person!);
}
print(person is Object);
}
..
------> 联级操作(连缀操作)
class Person {
String name = 张三;
int age = 20;
Person(this.name, this.age);
void showInfo() {
print(${this.name} ---------- ${this.age});
}
}
void main() {
var p = new Person(小红, 11);
p.showInfo();
// 此代码相当于 下面代码 sart
p.age = 25;
p.name = aimee;
p.showInfo();
// 此代码相当于 下面代码 end
p
..name = 小明
..age = 12
..showInfo(); // 连缀 仅在最后一个加号中;
}
10.3.面向对象的三大特性之一 继承
1.子类使用extends继承父类的关键字;
2.子类继承Long类中可见的属性和方法。 但不继承构造函数;
3.子类可以复制父类的方法。 getter 和 setter;
// 子类继承使用extends;
// 子类可以调用父类的方法和属性;
// 重写父类方法就是编写一个与父类方法同名的函数;
// 子类自定义方法调用父类方法。super.say();
class Person {
String name;
int age;
Person(this.name, this.age); // 构造函数 唯一
Person.hello(this.name, this.age); // 命名构造函数 可以多个
void showInfo() {
print(${this.name} ---------- ${this.age});
}
void say(){
print("hello say");
}
}
class Student extends Person {
String sex = 男;
// Student(String name, int age, String sex) : super(name, age) { // 完全访问与父类构造函数相同。
Student(String name, int age, String sex) : super.hello(name, age) { // 子类构造函数添加新参数。
this.sex = sex;
}
void speak() {
print(${this.name} - ${this.age} - ${this.sex} 你好,我是一个子类的自定义方法。);
super.say(); // 子类自定义方法调用父类方法;
}
// 复制父类方法 当调用一个子类时,在重写该子类之后调用有限数量的方法;
@override
void showInfo() {
print(${this.name} - ${this.age} - ${this.sex} 你好,我是覆盖父类的子类的方法。);
}
}
void main() {
Student stu = new Student(张磊磊, 22, 男);
stu.showInfo(); // 调用继承父类的方法。 如果子类重写(父类方法名与子类方法名相同),则首先调用子类的方法;
stu.speak(); // 调用您定义的方法。
}
11.Dart中 抽象类 多态 和接口
11.1抽象类中的抽象类:主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口;
!!!!
在抽象方法中,没有 方法体
即 {}
该方法称为抽象方法。 !!!!
abstract class Animal {
run(); // 抽象方法 定义标准类似于告诉继承此类的所有子类必须具有此方法。抽象类中与普通方法的不同之处在于没有方法体{};
eat(String foods); // 抽象方法 定义标准类似于告诉继承此类的所有子类必须具有此方法。抽象类中与普通方法的不同之处在于没有方法体{};
void goHome() { // 抽象类中的普通方法就是这样定义的。
print(我是一个在抽象类中定义的普通方法。 goHome!);
}
}
class Cat extends Animal {
@override // 重写抽象方法。。。。。。
eat(String foods) {
print(抽象类在父类中定义,子类重写,猫吃。${foods});
}
@override // 重写抽象方法。。。。。。
run() {
print(在父类中定义了抽象类,子类重写了,猫跑了。);
goHome();
}
}
class Dog extends Animal {
@override // 重写抽象方法。。。。。。
eat(String foods) {
print(抽象类在父类中定义,子类重写,吃老本。${foods});
}
@override // 重写抽象方法。。。。。。
run() {
print(在父类中定义了抽象类,子类重写了,狗跑了。);
goHome(); // 调用父类中的普通方法。
}
}
void main() {
Dog dog = new Dog();
dog.run();
dog.eat(骨头);
Cat cat = new Cat();
dog.run();
cat.eat(小鱼);
}
11.2 多态
允许将子类类型的指针赋给父类类型的指针。相同的函数调用会有不同的执行效果。
子类的实现将一个引用分配给父类。
简而言之:父类定义的方法不实现,让继承的子类实现,每个子类都有不同的表现。
abstract class Animal {
eat(); // 抽象方法 定义一个标准,类似于告诉所有继承这个类的人都必须有这个方法。
}
class Cat extends Animal {
@override // 重写抽象方法。。。。。。
eat() {
print(抽象类在父类中定义,子类重写,猫吃。鱼);
}
run() {
print(在父类中定义了抽象类,子类重写了,猫跑了。);
}
}
class Dog extends Animal {
@override // 重写抽象方法。。。。。。
eat() {
print(抽象类在父类中定义,子类重写,吃老本。肉 );
}
run() {
print(在父类中定义了抽象类,子类重写了,狗跑了。);
}
}
void main() {
// 这不实现多态,直接调用子类的方法;
Dog dog = new Dog();
dog.eat();
dog.run();
// 这个cat您只能调用父类中声明的抽象方法,但是eat分配给父类的。eat;
Animal cat = new Cat();
cat.eat();
}
11.3 接口 用implements关键字实施 且封装
实现案例 ,想要两个链接来发送数据
在lib下,新建oss.dart;
abstract class Db {
late String url;
add(String data);
}
// 使用接口
class Oss implements Db {
@override
late String url;
@override
add(String data) {
print(我这里是Oss类向${url}添加的数据:${data});
}
}
在lib下,新建sql.dart;
abstract class Db {
late String url;
add(String data);
}
// 使用接口
class mySql implements Db {
@override
String url;
mySql(this.url); // 子类构造函数
@override
add(String data) {
print(我这里是mySql类向${url}添加的数据:${data});
}
}
您可以随意创建新的使用界面。
import lib/sql.dart;
void main() {
var sql = new mySql(www.baidu.com); // 实例化的对象
sql.add(我是爱之鼠!); //调用子类方法
var oss = new Oss(); // 实例化的对象
oss.url = www.qq.com; // 子类直接赋值
oss.add(我也是爱鼠!); // 调用子类方法
}
11.4 使用多个接口以逗号分隔。
class Anima implements Animal, Eat {}
abstract class Animal {
late String name;
}
abstract class Eat {
eat(String foods);
}
class Anima implements Animal, Eat {
@override
String name;
Anima(this.name);
@override
eat(String foods) {
print(我是${this.name} 我吃了${foods});
}
}
void main() {
Anima cat = new Anima(小猫);
cat.eat(小鱼儿);
Anima dog = new Anima(小狗);
dog.eat(大骨头儿);
}
12 mixins混搭功能的使用!mixins与继承一起使用!
实现多重继承的功能!
具体情况如下:
解析:
1.只能是干净的class ,不能是抽象类;
2.被mixins该类不能有构造函数,也不能继承其他类;
3.一个类可以与多个类混合,with A,B还包括继承和重新混合。 extends C with A ,B;
4.他既不是继承人,也不是接口;
5.mixins实例类型是什么?很简单,mixins类型是超类的子类型;
class Animal {
late String name;
Animal(this.name);
}
class Eat {
eat(String foods) {
print(我吃了${foods}了,触发Eat方法了);
}
}
class Play {
play(String ball) {
print(我玩了${ball}了,触发Play方法了);
}
}
class Anima extends Animal with Eat, Play {
Anima(String name) : super(name);
@override
play(String ball) {
print(${this.name}玩了${ball}了,触发Play方法了);
}
@override
eat(String foods) {
print(${this.name}吃了${foods}了,触发Eat方法了);
}
}
void main() {
Anima an = new Anima(Aimee);
an.eat(苹果);
an.play(篮球);
}
注意:如果有很多复制方法,请遵循 最后一次调用覆盖了前面的方法;
-
泛型类 泛型方法 泛型接口 泛型mixins 的使用
自己的理解:打印和接收的参数可以是string ,int ,double,map,list 各种,不能一个参数类型写方法调用,用泛型,你发什么,我拿什么
注:使用泛型是为了避免冗余代码。例如,由于类型不同而编写了两个类。检查传输和连接的参数。
定义泛型方法:
T Hello(T value){
return value;
}
第一个 T 返回值为泛型;
未指定此选项!
第二个 T 调用该方法时必须指定该类型;
第三个 T 表示接收参数是泛型;
// 这里定义 您可以接收任何类型;前提是在创建时未指定该类型。如果创建指定类型,则只能接收指定类型的参数;
class SaySomething {
specak(T things) {
print(定义泛型类,并且${T}类型话-${things});
}
}
// mixin 泛型使用
class Person with SaySomething {
var name;
Person(this.name);
}
// 接口类型 泛型使用
class Animal implements SaySomething {
var name;
Animal(this.name);
@override
specak(T things) {
print(我是${name} 我的叫声${things});
}
}
//继承 泛型使用
class Student extends SaySomething {
var name;
Student(this.name);
}
void main(List args) {
SaySomething sayString = new SaySomething();
sayString.specak(我是一根弦);
// sayString.specak(33); // 报错
SaySomething sayInt = new SaySomething();
sayInt.specak(12334);
// sayInt.specak(asdfsd);// 报错
// mixins 使用泛型
Person person = new Person(王小二);
person.specak(11);
// person.specak(things); // 报错
// 该接口使用泛型。
Animal animal = new Animal(小猫咪);
animal.specak(喵喵喵);
// animal.specak(111); // 报错
// 继承使用泛型 初始化指定的string类型 只能接到string类型,传给别人不能;
Student stu = new Student(王一博);
stu.specak(老师好);
// stu.specak(111); // 报错
}
14 Dart 中的库 自定义库 系统库 第三方库
14.1 自定义库
类抽离lib文件夹下 需要使用import 引入 ;这称为自定义库;
import lib/Animal.dart;
14.2 系统内置库
import dart:math;// 跳转到内置库,查看如何使用它。
void main() {
print(max(21, 22));
}
14.3 async 和await的使用
async 是使该方法成为异步的
await 正在等待异步方法执行完成。
只有async要使用的方法await一种一种关键字调用方法
如果呼叫其他async方法必须使用await关键字
void main() async { // 只有async要使用的方法await一种一种关键字调用方法
await sayHello(); // 如果呼叫其他async方法必须使用await关键字
}
// 异步方法
sayHello() async {
print(hello world);
}
注意:将异步方法更改为同步方法。await;
14.4 第三方库的使用
1.在下面的网站上找到要使用的图书馆。
https://pub.dev/packages
https://pub.flutter-io.cn/packages
https://pub.dartlang.org/flutter/
2.根目录创建一个文件。pubspec.yaml 文件,如下所示。
name: my_wechat
description: A new Flutter project.
3.配置 dependencies,查看文档installing 。
dependencies:
http: ^0.13.4
4.运行 pub get 获取远程磁带库。
5.看看被引用到仓库中以供使用的文件。
15.Dart 2.13以下是一些新功能 Null safety、late 关键字,空类型声明符?,非空断言!,required 关键字;
15.1 Null safety 对应中文 空安全 、?可控型
? 可空类型 : int? a = 1; // a 是一个空类型
? 可空方法 : String? sayHello(things){} // sayHello 是一个空方法
! 类型断言 : print(name!.length); // 类型断言:Ifname不是null如果长度相等,将打印该长度null将引发异常;
// 方法可空
String? sayHello(things) {
print(things != null);
if (things != null) {
return things;
}
return null;
}
print(sayHello(艾米的猫-傻钢));
// 类型可空
int? a = 1; // A是一个空类型
a = null; // 空安全 校验
print(a);
// 类型断言!
String? name = this.is.str;
// name = null;
print(name!.length); // 类型断言:Ifname不能与null如果长度相等,将打印该长度null将引发异常;
15.2 late 关键字 主要用于类中自定义变量的延迟初始化
也就是说,类不给变量初始化就会报告错误,变量定义加。late此字段标识此字段,稍后将通过该方法为其赋值。setName来赋值name和age;
late String name; //延迟的初始化值
class Person {
late String name;
late int age;
void setName(String name, int age) {
this.name = name;
this.age = age;
}
}
void main() {
Person person = new Person();
person.setName(沙钢, 11);
}
15.3 required 关键字 内置修改器 参数必须传递的含义
class Person {
String name;
int? age;
Person({required this.name, this.age}); // 以下是缩写名称传输参数。
void printName() {
print("${this.name} --- ${this.age == null ? 未知 : this.age}");
}
}
void main() {
Person person = new Person(name: 颤三, age: 20); // 传输参数必须命名为
Person persons = new Person(name: 颤三);
person.printName();
persons.printName();
}
总结
提示:本文是一篇前端学习文章flutter过程中,如果有歧义,希望大家有很大的宝贵意见。
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除