Flutter学习笔记01: Flutter环境配置与Dart 基础

1、开发准备

1.1 Dart 中文官网

https://dart.cn/

1.2 Win10下环境搭建

1.2.1 如果安装了Flutter-SDK,其实也可以直接使用里面的dart - sdk

image.png
image.png

1.2.2 如果之前没有安装 Flutter-SDK,请看如下步骤(在线方式)

安装 包管理器 chocolatey
  • 点击右下级角的开始按钮,输入 cmd ,选择以管理员权限运行
image.png

Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

  • 输入如下命令
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"

image.png
  • 检测安装是否成功
choco -v

image.png
安装 dart-sdk
choco install dart-sdk

choco upgrade dart-sdk

1.2.3 离线方式安装,直接下载压缩包

1.3 开发工具选择

  • IntelliJ IDEA (以这个为例)

  • Android Studio

  • 其它

1.4 插件的安装

在线方式

image.png

image.png

image.png

离线方式

  • 查看跟IDEA对应的插件版本


    image.png
  • 去插件官网查找对应的版本

https://plugins.jetbrains.com/plugin/6351-dart/versions

image.png

1.5 项目创建

image.png
image.png
  • 运行出现报错:Setting VM flags failed: Unrecognized flags: checked
image.png
  • 把 Checked mode 勾取消即可


    image.png
image.png

2、数据类型

2.1 变量与常量

变量

  • 使用var声明变量,可赋予不同类型的值

  • 未初始化时,默认值为null

  • 使用fianl声明一个只能赋值一次的变量

image.png

常量

  • 使用const声明常量

  • 使用const声明的必须是编译期常量

  • const 与 final有着本质的区别

    1)在定义const常量时,你必须直接赋一个字面量,而不能是一个变量或者公式;

    2)在定义final常量时,如何赋值就无所谓了,但赋值后就不能再改了

image.png

2.2 内置类型

2.2.1 数值型-Number

  • Int 整型

  • double 浮点型

image.png
数值型操作
  • 运算符: +、 -、 *、 /、 ~/、 %
image.png
  • 常用属性:isNaN、 isEven、 isOdd等
image.png

image.png
  • 常用方法:abs()、round()、floor()、ceil()、toInt()、toDouble()


    image.png

2.2.2 字符串-String

字符串创建
  • 使用单引号,双引号创建字符串

  • 使用三个引号或双引号创建多行字符串

  • 使用r创建原始raw字符串

image.png

2.2.3 布尔型-Boolean

  • 使用bool表示布尔类型

  • 布尔值只有true 和 false

image.png

2.2.4 列表-List

创建
  • 创建List: var list = [1,2,3];
image.png
  • 创建不可变的List:var list = const [1,2,3];
image.png
  • 构造创建:var list = new List();
常用操作
  • List.length

  • List.add()

  • List.insert()

  • List.remove()

  • List.clear()

  • List.indexOf()

  • List.lastIndexOf()

  • List.sort()

  • List.sublist()

  • List.shuffle()

  • List.asMap()

  • List.forEach()

    var list = ["hello","dart"];
    print(list.length);

    list.add("java");
    print(list);

    list.remove("java");
    print(list);

    print(list.indexOf("dart"));
    print(list.indexOf("java"));

    list.insert(0, "2020");
    print(list);

    print(list.sublist(1));

    print(list.reversed);

    list.sort();
    print(list);

    list.clear();
    print(list);

2
[hello, dart, java]
[hello, dart]
1
-1
[2020, hello, dart]
[hello, dart]
(dart, hello, 2020)
[2020, dart, hello]
[]

2.2.5 键值对-Map

  • 创建
  1. 创建Map
var language = {"first":"Dart", "second" : "java"};

  1. 创建不可变Map
var language = const {"first":"Dart", "second" : "java"};

  1. 构造创建
var language = new Map();

  • 常用操作

1)Map.length

2)Map.isEmpty()、Map.isNotEmpty()

3)Map.Keys、 Map.values

4)Map.containsKey()、Map.containsValue()

5)Map.remove()

6)Map.forEach()

2.2.6 Runes、Symbols

image.png

3、运算符

3.1 算术运算符

  • 加减乘除: +、-、*、/、~/、%

  • 递增递减:++var、var++、--var、var--

3.2 关系运算符

  • 运算符:==、!=、>、<、>=、<=

  • 判断内容是否相同使用 ==

3.3 逻辑运算符

  • 运算符:!、&&、||

  • 针对布尔类型运算

3.4 赋值运算符

  • 基础运算符:=、??=

  • 复合运算符:+=、-=、*=、/=、%=、~/=

3.5 条件表达式

  • 三目运算符:condition?expr1 : expr2

  • ?? 运算符:expr1 ?? expr2

4、控制语句

4.1 if语句

  • if 语句

  • if...else if 语句

  • if...else if ...else 语句

4.2 for语句

  • for 循环

  • for ... in循环

4.3 while语句

  • while 循环

  • do ... while循环

4.4 break 和 continue语句

  • 终止循环:break

  • 跳出当前循环:continue

4.5 switch...case语句

  • 比较类型:num、String、编译期常量

  • 非空case必须有一个break

  • default 处理默认情况

  • continue跳转标签

image.png

5、方法

5.1 方法的定义

  • 方法的定义与使用
返回类型  方法名 (参数1,参数2...){
    方法体

    return 返回值
}
image.png
  • 方法的特性

  • 方法也是对象,并且有具体类型Function

  • 返回值类型、参数类型都可省略

  • 箭头语法: => expr 是 { return expr; }缩写。只适用于一个表达式

  • 方法都有返回值。如果没有指定,默认 return null 最后一句

5.2 可选参数

  • 可选命名参数:{param1, param2, ...}

  • 可选位置参数:{param1,param2, ...}

  • 如果存在具体参数,可选参数声明,必须在参数后面

5.3 默认参数值

  • 使用 = 在可选参数指定默认值

  • 默认值只能是编译时常量

5.4 方法对象

  • 方法可作为对象赋值给其它变量

  • 方法可作为参数传递给其它方法

5.5 匿名方法

  • 定义
(参数1. 参数2, ...) {

    方法体

    return 返回值

}

  • 特性

  • 可赋值给变量,通过变量进行调用

  • 可在其它方法中直接调用或传递给其它方法

5.6 闭包

  • 闭包是一个方法(对象)

  • 闭包定义在其它方法内部

  • 闭包能够访问外部方法内的局部变量,并持有其状态

void main(){

    var func = a();
    func();
    func();
    func();

}

a(){
  int count = 0;

  //闭包
//  printCount(){
//    print(count++);
//  }
//  return printCount;

  // 更多是使用匿名方式的闭包
  return (){
    print(count++);
  };
}

6、Dart 面向对象编程

6.1 类与对象

  • 类与对象

  • 使用关键字 class声明一个类

  • 使用关键字new 创建一个对象,new 可省略

  • 所有对象都继承于 Object类

void main(){
  
  var person = new Person();
  
}

class Person{
  int age;
  String name;
  
}

  • 属性与方法

    1)属性默认会生成getter 和 setter方法

    2)使用 final声明的属性只有 getter方法

    3)属性和方法通过 . 访问

    4)方法不能被重载



void main(){
  var person = new Person();
  person.name = "追梦小乐";
  person.age = 20;
  print(person.name);
  print(person.age);
  person.work();
  print(person.address);
}

class Person{
  int age;
  String name;
  final String address = "";
  void work(){
    print("姓名:$name  年龄:$age , is working.......");
  }

}

  • 类及成员的可见性

    1)Dart 中的可见性以 library (库)为单位

    2)默认情况下,每一个 Dart 文件就是一个库

    3)使用 _ 表示库的私有性

    4)使用 import 导入库

6.2 计算属性

  • 顾名思义,计算属性的值是通过计算而来,本身不存储值

  • 计算属性赋值,其实是通过计算转换到其它实例变量



void main(){
  var rect = new Rectangle();
  rect.width = 10;
  rect.height = 20;
  print(rect.area);

  rect.area = 200;
  print(rect.width);
}

class Rectangle {

  num width,height;

  //计算属性
//  num get area {
//    return width * height;
//  }

    //计算属性简写模式
    num get area => width * height;

    set area(value){
      width = value / 10;
    }
}

6.3 构造方法

  • 默认构造方法

    1)如果没有自定义构造方法,则会有个默认构造方法


void main(){
  
}

class Person{
  int age;
  String name;
  final String gender = null;
  
  Person(){
    
  }
  
  void work(){
    print("working =============");
  }
}

  • 自定义构造方法

    1)如果存在自定义构造方法,则默认构造方法无效


void main(){
  Person person = new Person(20, "追梦小乐", "女");
}

class Person{
  int age;
  String name;
  final String gender;
  
  //语法糖形式
  Person(this.age,this.name,this.gender);
  
    // 一般形式,虽说跟语法糖形式作用一样,但是有个区别,就是final修饰的变量,在这里是不能被赋值的
//  Person(int age,String name,String gender){
//    this.age = age;
//    this.name = name;
//    this.gender = gender;
//  }
  
  void work(){
    print("working ===============");
  }
}

  • 命名构造方法

    1)构造方法不能重载


void main(){
  Person person = new Person(20, "追梦小乐", "女");
  new Person.withName("风行者", "男");
  new Person.withAge(20, "男");
}

class Person{
  int age;
  String name;
  final String gender;

  //语法糖形式
  Person(this.age,this.name,this.gender);

  Person.withName(String name, this.gender){
    this.name = name;
  }

  Person.withAge(int age, this.gender){
    this.age = age;
  }

  void work(){
    print("working ===============");
  }
}

6.4 常量构造方法

image.png
  • 如果类是不可变状态,可以把对象定义为编译时常量

  • 使用 const 声明


void main(){
  const person = const Person(20, "追梦小乐", "女");
  person.work();
}

class Person{
  final int age;
  final String name;
  final String gender;

  //语法糖形式
  const Person(this.age,this.name,this.gender);

  void work(){
    print("working ===============");
  }
}

6.5 工厂构造方法

image.png

class Logger{

  final String name;

  static final Map _cache = {};

  factory Logger(String name){
    return Logger._internal("dart");
  }

  Logger._internal(this.name);

  void log(String msg){
    print(msg);
  }

}

6.6 初始化列表

image.png

void main(){
  var person = Person(20, "追梦小乐", "女");
  person.work();
}

class Person{
  int age;
  String name;
  final String gender;

  //语法糖形式
  Person(this.age,this.name,this.gender);

  Person.withName(Map map) : gender = map["gender"]{
    this.name = map["name"];
    this.age = map["age"];
  }

  void work(){
    print("working ===============");
  }
}

6.7 静态成员

image.png

void main(){
  var page = new Page();
  page.scrollUp();
  Page.scrollDown();
}

class Page{

  static const int maxPage = 10;

  static int currentPage = 1;

  static void scrollDown(){
    currentPage = 1;
    print("scrollDown======");
  }

  void scrollUp(){
    currentPage++;
    print("scrollUp======");
  }
}

6.8 对象操作符

  • 条件成员访问 ?.

void main(){
  Person person;
  person ?.work();
}

class Person{
  String name;
  int age;
  
  void work(){
    print("Work......");
  }
}

  • 类型转换:as

void main(){
  var person;
  person = "";
  person = new Person();
  (person as Person).work();
}

class Person{
  String name;
  int age;

  void work(){
    print("Work......");
  }
}

  • 是否指定类型 :is , is!

void main(){
  var person;
  person = "";
  if(person is Person){
    person.work();
  }
}

class Person{
  String name;
  int age;

  void work(){
    print("Work......");
  }
}

  • 级联操作: ..

void main(){
  Person person = new Person();
  person..name = "追梦小乐"
        ..age = 20
        ..work();
}

class Person{
  String name;
  int age;

  void work(){
    print("Work......");
  }
}

6.9 对象call方法

image.png

void main(){
  var person = new Person();
  person.call("追梦小乐", 20);
}

class Person{
  String name;
  int age;
  
  //返回值可以有,也可以为空,可以有参也可以无参
  String call(String name,int age){
    return "name is $name, age is $age";
  }
  
}

你是怎样理解父类继承,接口实现和混入的?我们应该在什么场景下使用它们?

1.一般来讲,单继承,多实现,混入是多继承
A.继承是子类需要复用父类的方法实现
B.实现接口是复用接口的参数,返回值,和方法名,但不复用方法的实现,在Dart中实现抽象类 更像在java中实现用interface修饰的接口
C.混入是多继承,当被混入的类有多个同名方法时,调用子类的该方法时,会调用with声明的最后一个拥有该方法的类中的该方法,同时混入中的父类不能继承

在父类继承的场景中,父类子类之间的构造函数执行顺序是怎样的?如果父类有多个构造函数,子类也有多个构造函数,如何从代码层面确保父类子类之间构造函数的正确调用?


class Point {
  num x, y;
  Point() : this.make(0,0);
  Point.left(x) : this.make(x,0);
  Point.right(y) : this.make(0,y);
  Point.make(this.x, this.y);
  void printInfo() => print('($x,$y)');
}

class Vector extends Point{
  num z = 0;
/*5个构造函数
  Vector
  Vector.left;
  Vector.middle
  Vector.right
  Vector.make
*/
  @override
  void printInfo() => print('($x,$y,$z)'); //覆写了printInfo实现
}

你可能感兴趣的:(Flutter学习笔记01: Flutter环境配置与Dart 基础)