首页 > 其他分享 >Flutter/Dart第20天:Dart 3.0新特性之类型修饰符

Flutter/Dart第20天:Dart 3.0新特性之类型修饰符

时间:2023-11-05 15:46:19浏览次数:38  
标签:20 子类 修饰符 Dart 实例 sealed Vehicle class

Dart官方文档:https://dart.dev/language/class-modifiers

重要说明:本博客基于Dart官网文档,但并不是简单的对官网进行翻译,在覆盖核心功能情况下,我会根据个人研发经验,加入自己的一些扩展问题和场景验证。

类型修饰符主要是控制类或者Mixin如何被使用,包括在库内部和外部使用。修饰符关键字出现在类型或Mixin申明的前面,如abstract class通过abstract修饰符定义了一个抽象类。

可用于声明类的修饰符关键字列表如下:

  • abstract
  • base
  • final
  • interface
  • sealed
  • mixin

约束:上面的修饰符列表,只有base能用于Mixin类型;同时,上诉修饰符不能用于包括enumtypedefextension等类型声明。

实战:当我们决定要使用修饰符时,可能需要考虑一下类的预期用途和类需要提供哪些行为。

无修饰符

当我们定义类或者Mixin时,不希望对构造函数或者子类进行限制时,我们可以不使用修饰符。

当类或者Mixin没有修饰符时,默认情况下,可以对这些类或者Mixin进行以下操作:

  • 通过构造函数创建类实例
  • 通过继承类来创建子类
  • 实现类或者Mixin的接口
  • 混入Mixin或者Mixin类

abstract修饰符(抽象类)

使用场景:当我们定义了一个类(即:抽象类),但又没有完整地实现了它所有的接口时使用(和Java语言一样),请使用abstract修饰符。

约束:抽象类不能被实例化;一般情况,抽象类都包含抽象方法。

// 抽象类
abstract class Vehicle {
  void moveForward(int meters);
}

// 实现类
class MockVehicle implements Vehicle {
  @override
  void moveForward(int meters) {
    // ...
  }
}

base修饰符(基类)

使用场景:当我们用base修饰符定义了一个类或者Mixin时(即:基类),那么这个基类的实现只能基类所在库内。这样做的目的:

  • 每当创建子类实例时,基类的构造函数被调用
  • 所有已经实现的私有成员都在子类中
  • 在基类中新增加的成员会被所有子类继承(除非:子类中申明了同名的成员但并不兼容的签名。如:子类申明了同名方法,但是方法入参或者返回结果与基类不兼容)

实战:为了保证基类不会被破坏,子类必须使用basefinal或者sealed修饰符。

如下代码样例,基类可以实例化、被继承,但是不能被实现:

// 基类
base class Vehicle {
  void moveForward(int meters) {
    // ...
  }
}

// 1. 实例化
Vehicle myVehicle = Vehicle();

// 2. 被继承
base class Car extends Vehicle {
  int passengers = 4;
  // ...
}

// 3. ERROR:不能被实现
base class MockVehicle implements Vehicle {
  @override
  void moveForward() {
    // ...
  }
}

interface修饰符(接口类)

使用场景:使用interface修饰符定义一个接口。接口可以被外部库实现,但是不能被继承。这样做的目的:

  • 当类的一个实例方法使用this调用另一个实例方法时,它总是调用同一个库的实例方法
  • 为了避免不可预期的方法调用,其他库不能重新接口已有的方法

如下代码样例,接口类可以实例化、被实现,但是不能被继承:

// a.dart 接口类
interface class Vehicle {
  void moveForward(int meters) {
    // ...
  }
}

//
// b.dart
//
import 'a.dart';

// 1. 实例化
Vehicle myVehicle = Vehicle();

// 2. 被实现
class MockVehicle implements Vehicle {
  @override
  void moveForward(int meters) {
    // ...
  }
}

// 3. ERROR: 不能被继承
class Car extends Vehicle {
  int passengers = 4;
  // ...
}

abstrace interface(抽象接口类)

一般情况下,我们使用interface来定义纯粹接口。

当我们使用abstract interface class组合修饰符时,可以定义一个抽象接口类:它即有接口类的功能(可被实现,但不能被继承),也有抽象类的功能(有抽象成员)。

final修饰符(不可变类)

使用场景:当使用final修饰符时,表示该类不能被其他库继承和实现(和Java还有点不一样)。这样做的目的:

  • 可以安全地进行API变更
  • 该类不会被第三方子类覆盖,因此可以放心调用实例方法

约束:final不可变类可以在本库中被继承和实现,final修饰符包含了base修饰符特性,因此,子类必须使用basefinal或者sealed修饰符。

// a.dart 接口类
final class Vehicle {
  void moveForward(int meters) {
    // ...
  }
}

//
// b.dart
//
import 'a.dart';

// 1. 实例化
Vehicle myVehicle = Vehicle();

// 2. ERROR: 不能被继承
class Car extends Vehicle {
  int passengers = 4;
  // ...
}

class MockVehicle implements Vehicle {
  // 3. ERROR: 不能被实现
  @override
  void moveForward(int meters) {
    // ...
  }
}

sealed修饰符(密封类)

使用场景:当我们定义了一个类(即:密封类),且明确该类的所有子类集合时,请使用sealed修饰符。这允许我们通过switch穷举所有的子类型。

约束:sealed修饰的类,禁止被其他库继承或者实现,它隐含abstract修饰符:

  • 不能被实例化
  • 可以有工厂构造函数
  • 可以定义构造函数,子类可直接使用
  • 子类并不是abstract抽象类

编译器可以知道所有sealed修饰符类的子类(因为他们在同一个库中),这样在switch中,如未穷举,编译器能发出错误警告!

// 密封类
sealed class Vehicle {}

class Car extends Vehicle {}

class Truck implements Vehicle {}

class Bicycle extends Vehicle {}

// 1. ERROR: 不能被实例化
Vehicle myVehicle = Vehicle();

// 2. 子类可以被实例化
Vehicle myCar = Car();

String getVehicleSound(Vehicle vehicle) {
  // 3. ERROR: switch中子类未穷举(还有Bicycle子类)
  return switch (vehicle) {
    Car() => 'vroom',
    Truck() => 'VROOOOMM',
  };
}

switch中,如果我们不想穷举sealed类的子类;又或者以后还会增加子类,但又不想破坏API设计,我也可以使用final修饰符。关于finalsealed修饰符的深入比较,请稍等本博客的下一个博客介绍(请容许我卖个关子!)。

组合修饰符

通过组合修饰符,可以起到叠加限制效果。我们申明类时,按照顺序,可以叠加的修饰符:

  • 可选的abstract修饰符:类包含抽象成员,且不能被实例化
  • 可选的baseinterfacefinalsealed修饰符:限制其他库的子类型
  • 可选的mixin修饰符:类是否可被混入
  • 必选的class类关键字

部分修饰符是不能组合使用,因为他们可能多余或者矛盾互斥:

  • abstract修饰符和sealed修饰符:原因是sealed隐含了abstract修饰符
  • interfacefinalsealed修饰符和mixin修饰符:原因是这些修饰符都禁止被混入

完整的有效的修饰符组合列表如下:

image


我的本博客原地址:https://ntopic.cn/p/2023110501


标签:20,子类,修饰符,Dart,实例,sealed,Vehicle,class
From: https://www.cnblogs.com/obullxl/p/NTopic2023110501.html

相关文章

  • 2023-2024-1 20231405《计算机基础与程序设计》第六周学习总结
    2023-2024-120231405《计算机基础与程序设计》第六周学习总结作业信息作业属于哪个课程https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP作业要求在哪里https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP/homework/13009作业的目标自学《计算机......
  • 【洛谷 P1909】[NOIP2016 普及组] 买铅笔 题解(打擂台法)
    [NOIP2016普及组]买铅笔题目背景NOIP2016普及组T1题目描述P老师需要去商店买支铅笔作为小朋友们参加NOIP的礼物。她发现商店一共有种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平起见,P老师决定只买同一种包装的铅笔。商店不允许将铅笔的包装......
  • Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!) B. Kuroni an
    Problem-1305B-Codeforces 啦啦啦,这题题目有点长,概括一下就是,希望将所有()匹配的括号去掉问你需要操作多少次 双指针,一个i一个j,从前往后记录匹配的括号如果发现:1.括号匹配2.i<jok,就放入ans (⊙o⊙)…,最后记得sort一遍ans,第一遍因为这个wa了一发 #include......
  • 20.7 OpenSSL 套接字SSL加密传输
    OpenSSL中的SSL加密是通过SSL/TLS协议来实现的。SSL/TLS是一种安全通信协议,可以保障通信双方之间的通信安全性和数据完整性。在SSL/TLS协议中,加密算法是其中最核心的组成部分之一,SSL可以使用各类加密算法进行密钥协商,一般来说会使用RSA等加密算法,使用TLS加密针对服务端来说......
  • Adobe Photoshop 2023 最新激活图文方法(亲测有效)
    介绍AdobePhotoshop2023可以创建关于世界上最好的照片,设计师Photoshop使用易于使用的工具和直观的模板将创意世界向前推进。即使是初学者也能创造一些不可思议的东西。Photoshop可以做任何事情,从图像编辑和图像编辑到数字绘图,动画和平面设计。它具有全方位的专业修图工具,具有强大......
  • 2023-2024-1 20231419 《计算机基础与程序设计》第六周学习总结
    2023-2024-120231419《计算机基础与程序设计》第六周学习总结作业信息这个作业属于哪个课程https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP这个作业要求在哪里https://www.cnblogs.com/rocedu/p/9577842.html#WEEK06这个作业的目标自学《计算机科学概......
  • 20211314王艺达学习笔记8
    Unix/Linux系统编程第五章定时器及时钟服务5.1硬件定时器定时器由时钟源和可编程计数器组成。时钟源会产生周期性电信号。计数器减为0时,计数器向CPU生成一个定时器中断,计数器周期称为定时器刻度,是系统的基本计时单元。5.2个人计时定时器实时时钟(RTC)即使在个人计算机关机......
  • 2023-2024-1 20231403 《计算机基础与程序设计》第六周学习总结
    作业信息这个作业属于哪个课程<班级的链接>(如2022-2023-1-计算机基础与程序设计)这个作业要求在哪里2023-2024-1计算机基础与程序设计第六周作业)这个作业的目标自学教材:计算机科学概论第7章并完成云班课测试《C语言程序设计》第5章并完成云班课测试作业正文h......
  • 20.7 OpenSSL 套接字SSL加密传输
    OpenSSL中的SSL加密是通过SSL/TLS协议来实现的。SSL/TLS是一种安全通信协议,可以保障通信双方之间的通信安全性和数据完整性。在SSL/TLS协议中,加密算法是其中最核心的组成部分之一,SSL可以使用各类加密算法进行密钥协商,一般来说会使用RSA等加密算法,使用TLS加密针对服务端来......
  • HHKB Programming Contest 2023(AtCoder Beginner Contest 327) 赛后总结
    HHKBProgrammingContest2023(AtCoderBeginnerContest327)赛后总结又没来得及写题解。。。赛时A-ab查找ab和ba,只要其中一者存在就行。#include<bits/stdc++.h>usingnamespacestd;intn;strings;intmain(){cin>>n>>s;cout<<(s.find("a......