Flutter开发02-Dart进阶

Flutter开发02-Dart进阶
type
status
date
slug
summary
tags
category
icon
password
😀
这里写文章的前言: Dart 语言提供了一系列的运算符和编程机制,使得开发者能够以简洁、高效的方式编写代码。

Dart进阶

Dart: https://dart.cn/

1.进阶运算符

1.1 空安全运算符

  • ?. 安全调用运算符:在调用对象的属性或方法前加上?.,如果对象为null则返回null,而不是抛出异常。
  • ?? 空合并运算符:如果左侧的表达式结果为null,则返回右侧的表达式结果;否则返回左侧的表达式结果。
  • ! 非空断言运算符:在表达式后加上!,可以断言表达式的结果非null,如果结果为null,则抛出异常。这个运算符在Dart的空安全特性中非常有用。

1.2 级联运算符 (..)

级联运算符允许在同一个对象上连续调用多个方法或访问多个字段,而不需要重复引用对象本身。这对于初始化和配置对象非常有用。

1.3 集合类型

Dart 提供了强大的集合类型,包括但不限于列表(List)、集合(Set)和映射(Map)。
  • List:有序集合,支持索引访问。可以容纳重复元素。
  • Set:无序集合,不支持索引访问。自动去除重复元素。
  • Map:键值对集合,键唯一。支持根据键访问值。
集合字面量和集合操作简化了数据处理,例如:

2.语法特性

Dart 是一种面向对象的语言,提供了丰富的面向对象编程特性:
  • 构造函数:除了默认构造函数和命名构造函数,Dart还支持工厂构造函数,允许构造函数返回对象实例。
  • 继承:通过extends关键字实现类的继承。
  • 接口:Dart 中没有特殊的interface关键字,任何类都可以作为接口被实现(使用implements关键字)。
  • Mixin:通过with关键字混入一个或多个mixin类,为类添加新的功能。

2.1 类的继承

Dart支持类的继承,可以通过关键字extends来实现。子类可以继承父类的属性和方法,并且可以重写父类的方法。例如:

2.2 接口

Dart中没有专门的interface关键字,而是通过类来实现接口。一个类可以实现多个接口。例如:

2.3 异步编程

Dart提供了内置的异步编程支持,使用asyncawait关键字可以方便地处理异步操作。例如:
Dart 的异步编程模型主要基于FutureStream对象,以及asyncawait关键字。
  • Future:代表一个潜在的值(或错误),这个值可以在将来某个时点被获取。Future广泛用于异步操作,如网络请求、文件IO等。
  • Stream:提供了一个数据序列,这些数据项可以逐个读取。Stream常用于处理异步事件或连续数据流,如用户输入、文件读取等。
  • 使用async标记的函数会返回一个Future,使得函数体内部可以使用await关键字等待异步操作完成,而不阻塞代码的执行。

2.4 异常处理

Dart使用try-catch块来捕获和处理异常。可以使用on关键字指定特定的异常类型,也可以使用catch来处理所有类型的异常。例如:
try-catch结构提供了捕获和处理异常的能力,finally块确保无论是否发生异常都会执行某些操作。

2.5 泛型扩展

泛型增加了代码的复用性和类型安全。通过泛型,可以定义在多种数据类型上操作的组件。
  • 使用泛型类时,可以创建具有不同类型参数的实例。
  • 泛型方法允许在方法调用时指定类型参数,提高了方法的灵活性和通用性。
例如,定义一个泛型类Box
可以创建存储不同类型的Box实例:

2.6 简单示例

上述示例,演示了Dart中的类、抽象类、泛型、继承和接口实现等基本概念。解释:
  1. 定义抽象类 Item
      • 抽象类不能被实例化,用 abstract 关键字标识。
      • 定义了一个抽象方法 use(),子类需要实现该方法。
  1. 定义类 Chest 实现接口 Item
      • 使用 implements 关键字实现 Item 接口。
      • 使用泛型 <T>,表示 Chest 可以存放任何类型的物品。
      • 构造函数中使用 this 将参数赋值给实例变量。
      • 实现了 use() 方法,打印出 Chest 中的物品数量。
  1. 定义类 Sword 实现接口 Item
      • 实现了 Item 接口中的 use() 方法,打印出 Sword 对应的伤害值。
  1. 定义类 DiamondSword 继承自 Sword
      • 重写了 damage 属性,将伤害值修改为 50。
  1. main 函数中:
      • 创建了一个 Chest 的实例 chest,并向其中放入了一个 DiamondSword 和一个普通的 Sword
      • 调用了 chest.use() 方法,打印出 Chest 中的物品数量。
      • 使用 for-in 循环遍历 chest 中的物品,分别调用它们的 use() 方法。

3.进阶语法学习

3.1 普通函数、匿名函数和箭头函数

1. 普通函数(Regular Functions)

普通函数是最基本的函数类型,它可以有返回值也可以没有(此时返回类型为void)。普通函数可以接收任意数量和类型的参数。

2. 匿名函数(Anonymous Functions)

匿名函数,又称为lambda闭包,是没有名称的函数。它们通常用于作为参数传递给其他函数或方法。

3. 箭头函数(Arrow Functions)

箭头函数是一种语法简洁的函数表达式适用于只包含一个表达式的函数体。使用**=>符号**指示。

3.2 命名构造函数和工厂函数

命名构造函数(Named Constructors)和工厂构造函数(Factory Constructors)都是Dart中提供的用于创建对象的特殊方法,它们各自有不同的用途和行为特征。

命名构造函数(Named Constructors)

  1. 目的:允许一个类有多个构造函数,每个构造函数都可以有不同的名称。
  1. 实例创建:每次调用命名构造函数时,都会创建该类的一个新实例(除非构造函数显式地返回现有的实例)。
  1. 初始化:可以使用命名构造函数来初始化类的实例变量,包括final变量。
  1. 使用场景:当你需要根据不同的数据或条件以不同的方式初始化类的实例时,可以使用命名构造函数。

工厂构造函数(Factory Constructors)

  1. 目的:允许构造函数不直接创建类的新实例,而是通过某种逻辑来决定返回哪个对象(可能是一个新实例,也可能是缓存的实例,甚至是子类的实例)。
  1. 实例创建:工厂构造函数可能不会创建新的实例。它可以返回一个已经存在的实例,或者根据条件返回不同的实例。
  1. 初始化:由于工厂构造函数可能不创建新的对象,因此不能用来初始化final变量。
  1. 使用场景:当你需要控制类的实例化过程,例如实现单例模式,或根据输入参数返回不同的子类实例时,可以使用工厂构造函数。

总结

  • 命名构造函数用于在同一个类中提供多种初始化方式,每次调用都会创建类的一个新实例(除非特别设计)。
  • 工厂构造函数是一种特殊类型的构造函数,它不会自动创建类的新实例,而是通过工厂构造函数的逻辑来决定返回哪个对象。这允许构造函数返回子类的实例,或者返回一个缓存的实例,从而实现更灵活的实例创建模式,如单例模式或者池模式。
    • 工厂构造函数使用factory关键字标记。与普通构造函数不同,工厂构造函数不需要初始化所有的final字段,也不会自动创建实例,它们通常用于以下场景:
    • 当你需要从构造函数中返回一个已经存在的实例而不是每次都创建一个新的实例时。
    • 当你希望返回一个子类的实例而非当前类的实例时。
    • 实现一个设计模式,比如单例模式。

3.3 类和实例的方法

1. 静态方法(Static Methods)

静态方法是属于类而不是类的实例的方法。静态方法不能访问类的实例变量或实例方法,但可以被类直接调用。

2. 实例方法(Instance Methods)

实例方法是定义在类中的函数,需要通过类的实例来调用。实例方法可以访问类的实例变量和其他实例方法。

3. Getter和Setter方法(Getter and Setter Methods)

Getter和Setter是特殊类型的方法,用于读取和设置对象的属性。虽然在Dart中你可以直接访问属性,但使用Getter和Setter可以提供更好的封装和数据验证。

4. 扩展方法(Extension Methods)

扩展方法允许你向现有类型添加新的方法,而无需修改原始类型的源代码或创建子类。

3.4 问题总结

  1. Dart中mixin混入和interface接口有什么区别?
    1. Mixin

    2. 定义:Mixin 是一种在多个类层次结构中重用类代码的方式。Mixin 允许你将一个类的方法和属性“混入”另一个类中,而不需要继承该类。Mixins 的目的是提供一种代码复用的机制,而不是表达类之间的任何类型关系。
    3. 使用:你可以使用 with 关键字将一个或多个 mixin 混入到一个类中。Mixin 类本身不能被实例化,也不能有构造函数。
    4. 特点
        • Mixin 可以访问调用者的方法和属性,因此它们可以操作调用者的状态。
        • 使用 mixin 可以避免多重继承所带来的复杂性和问题。
        • 一个类可以混入多个 mixin,以组合多个功能。
        • Mixin 可以使用 on 关键字指定其可被混入的类的类型约束。

      接口

    5. 定义:在 Dart 中,任何类都可以作为一个接口被其他类实现。接口定义了一个类必须拥有的方法和属性,但不提供实现。接口的目的是定义一个可以由多个类共享的协议。
    6. 使用:你可以通过 implements 关键字使一个类实现一个或多个接口。实现类必须重写接口中的所有方法和属性。
    7. 特点
        • 接口强制实现类遵循某种协议,提高了代码的一致性和可预测性。
        • 一个类可以实现多个接口,从而实现多重继承的效果。
        • 接口本身不提供任何方法或属性的实现。
        • 实现接口的类可以定义自己的状态和构造函数。

区别总结

  • 目的:Mixin 主要用于代码复用,接口主要用于定义协议和强制实现特定的方法集。
  • 实现方式:Mixin 使用 with 关键字混入,接口使用 implements 关键字实现。
  • 构造函数和状态:Mixin 不能有构造函数,也不是独立实例化的,它们可以直接访问使用它的类的状态;而接口不提供实现,实现接口的类负责提供构造函数和状态管理。
  • 类型关系:Mixin 不表达任何类型关系,而接口定义了一种类型协议,实现接口的类必须遵循这个协议。
上一篇
Flutter开发03-Dart高级
下一篇
Flutter开发01-Dart基础
Loading...