Flutter之Dart基础从零学原创

原创
小哥 3年前 (2022-11-11) 阅读数 173 #技术教程

加粗样式

提示:本文是一篇前端学习文章flutter过程中,如果有歧义,希望大家有很大的宝贵意见。

学习Dart 基础知识 移步这里
安装flutter环境相关 移步这里
flutter基本组件使用相关 移步这里

文章目录

前言

提示:想学好吗?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
  1. " ++ -- " 在赋值操作中,++在此之后,在计算之前赋值,++前面是作业中的第一个计算;

    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类型转换

  1. toString() 强制转换为字符串类型;

    var num = 123; var num1 = num.toString(); print(num1 is String);

  2. 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);

  3. 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(篮球);
}

注意:如果有很多复制方法,请遵循 最后一次调用覆盖了前面的方法;

  1. 泛型类 泛型方法 泛型接口 泛型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过程中,如果有歧义,希望大家有很大的宝贵意见。

学习Dart 基础知识 移步这里
安装flutter环境相关 移步这里
flutter基本组件使用相关 移步这里

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门