继续学习枯燥的Dart语言语法,目前的耐得住寂寞是为了将来学得“爽”做准备的!!!

异常:

Dart 提供了 Exception 和 Error 类型, 以及一些子类型。还可以定义自己的异常类型。但是,Dart 代码可以抛出任何非 null 对象为异常,不仅仅是实现了 Exception 或者 Error 的对象。

Exception类型:

其中常见的Exception如下:

Error类型:

抛出:

所有的 Dart 异常是非检查异常。 方法不一定声明了他们所抛出的异常, 并且你不要求捕获任何异常【这个Kotlin也差不多】。
Dart 代码可以抛出任何非 null 对象为异常,不仅仅是实现了 Exception 或者 Error 的对象。

捕获:

  • 可以使用on 或者 catch 来声明捕获语句,也可以 同时使用。使用 on 来指定异常类型,使用 catch 来 捕获异常对象。
  • catch() 可以带有一个或者两个参数, 第一个参数为抛出的异常对象, 第二个为堆栈信息 (一个 StackTrace 对象)。

    还可以用on来指定异常类型,如下:

    如果抛一个非error的呢?

    还可以用精确异常:

    也能这样写:

    完整的写法可以如下:

  • 可以使用rethrow把捕获的异常重新抛出。

类:

构造函数:

命名构造函数:

使用命名构造函数可以为一个类实现多个构造函数, 或者使用命名构造函数来更清晰的表明你的意图。

重定向构造函数:

一个重定向构造函数是没有代码的,在构造函数声明后,使用冒号调用其他构造函数。

初始化列表:

  • 在构造函数体执行之前可以初始化实例参数。 使用逗号分隔初始化表达式。
  • 初始化列表非常适合用来设置 final 变量的值。

调用超类构造函数:

  • 超类命名构造函数不会传递,如果希望使用超类中定义的命名构造函数创建子类,则必须在子类中实现该构造函数。
  • 如果超类没有默认构造函数, 则你需要手动的调用超类的其他构造函数。
  • 调用超类构造函数的参数无法访问 this。
  • 在构造函数的初始化列表中使用 super(),需要把它放到最后。

其中要注意一个细节:

常量构造函数:

  • 定义const构造函数要确保所有实例变量都是final。
  • const关键字放在构造函数名称之前。

注意必须是final修饰变量,换成const或去掉都是要报错的:

有啥用呢?再来看:

这种写法在未来flutter的学习中会大量运用到的。

工厂构造函数【用得很多】:

  • 工厂构造函数是一种构造函数,与普通构造函数不同,工厂函数不会自动生成实例,而是通过代码来决定返回的实例对象。
  • 如果一个构造函数并不总是返回一个新的对象,则使用 factory 来定义这个构造函数。
  • 工厂构造函数无法访问this。

要记住这样的写法,因为在未来实际场景中会大量看到~~

Setter和Getter:

  • 每个实例变量都隐含的具有一个 getter, 如果变量不是 final 的则还有一个 setter。
  • 可以通过实行 getter 和 setter 来创建新的属性, 使用 get 和 set 关键字定义 getter 和 setter。
  • getter 和 setter 的好处是,你可以开始使用实例变量,后来 你可以把实例变量用函数包裹起来,而调用你代码的地方不需要修改。

代码来瞅一下:

抽象类:

  • 不能被实例化,除非定义一个工厂构造函数。
  • 抽象类通常用来定义接口, 以及部分实现。
  • 抽象类通常具有抽象方法,抽象方法不需要关键字,以分号结束即可。
  • 接口方式使用时,需要重写抽象类的成员变量和方法,包括私有的。
  • 一个类可以implement一个普通类。Dart任何一个类都是接口。
  • 一个类可以implement多个接口。

比如说按摩可以有多个种类,咱们先来定义一个抽象的按摩类:

接下来来创建具体的子类,如下:

调用一下:

以上就是一种工厂方法的典型使用,需要特别注意:在Dart中木有interface关键字,abstract就可以当接口来用,下面再来看以继承的方式来使用:

这是第二种工厂模式的写法,对其有个大致印象既可,在之后的实际开发中会有用武之地滴。

可调用类:

实现call()方法可以让类像函数一样能够被调用。

Mixin:

  • 子类没有重写超类A方法的前提下,如果2个或多个超类拥有相同签名的A方法,那么子类会以继承的最后一个超类中的A方法为准。
  • 如果子类自己重写了A方法则以本身的A方法为准。

下面以这个场景为例:

下面来看下代码,看mixin是个啥东东?

void main() {
Bicycle().transport();
Motocycle().transport();
Car().transport();
} //交通抽象类
abstract class Transportation {
void transport();
} //自行车
class Bicycle extends Transportation {
String safeIndex() => "low"; String powerUnit() => "2个轮子"; String energy() => "脚蹬"; @override
void transport() {
print('Bicycle:\npowerUnit: ${powerUnit()}, safeIndex: ${safeIndex()}, energy: ${energy()}');
}
} //摩托车
class Motocycle extends Transportation {
String safeIndex() => "low"; String powerUnit() => "2个轮子"; String energy() => "汽油"; @override
void transport() {
print('Motocycle:\npowerUnit: ${powerUnit()}, safeIndex: ${safeIndex()}, energy: ${energy()}');
}
} //汽车
class Car extends Transportation {
String safeIndex() => "middle"; String powerUnit() => "4个轮子"; String energy() => "汽油"; @override
void transport() {
print('Car:\npowerUnit: ${powerUnit()}, safeIndex: ${safeIndex()}, energy: ${energy()}');
}
}

运行如下:

好,接下来要改造了,从上面的代码来看:

好,咱们将里面的行为再单独抽象一下,如下:

接下来咱们使用Mixin的方式来改造代码:

void main() {
Bicycle().transport();
Motocycle().transport();
Car().transport();
} //交通抽象类
abstract class Transportation {
void transport();
} //2个轮子
abstract class TwoWheelTransportation {
String powerUnit() => "2个轮子";
} //4个轮子
abstract class FourWheelTransportation {
String powerUnit() => "2个轮子";
} //低安全系数
abstract class LowSafeTransportation {
String safeIndex() => "low";
} //中安全系数
abstract class MiddleSafeTransportation {
String safeIndex() => "middle";
} //人工动力
abstract class BodyEnergyTransportation {
String energy() => "脚蹬";
} //汽油动力
abstract class GasEnergyTransportation {
String energy() => "汽油";
} //自行车
class Bicycle extends Transportation with LowSafeTransportation, BodyEnergyTransportation, TwoWheelTransportation { @override
void transport() {
print(
'Bicycle:\npowerUnit: ${powerUnit()}, safeIndex: ${safeIndex()}, energy: ${energy()}');
}
} //摩托车
class Motocycle extends Transportation with LowSafeTransportation, GasEnergyTransportation, TwoWheelTransportation { @override
void transport() {
print(
'Motocycle:\npowerUnit: ${powerUnit()}, safeIndex: ${safeIndex()}, energy: ${energy()}');
}
} //汽车
class Car extends Transportation with MiddleSafeTransportation, GasEnergyTransportation, FourWheelTransportation {
String safeIndex() => "middle"; String powerUnit() => "4个轮子"; String energy() => "汽油"; @override
void transport() {
print(
'Car:\npowerUnit: ${powerUnit()}, safeIndex: ${safeIndex()}, energy: ${energy()}');
}
}

其运行结果跟之前是一样的:

这里还涉及到一个顺序问题,下面再来看下:

调用一下:

这个结果可以发现:

这俩打印又能说明啥现象呢?

这块东东先有个大体印象吧,没有真实的项目做为操练也不可以意会得非常深刻。。

泛型:

泛型函数:

Dart1.21开始可以使用泛型函数。
泛型函数可以在以下几个地方使用类型参数:
<1> 函数的返回值类型。
<2> 参数的类型。
<3> 局部变量的类型。

构造函数泛型:

要在使用构造函数时指定一个或多个类型,可将类型放在类名称后面的尖括号<...>中。

泛型限制:

实现泛型类型时,您可能希望限制其参数的类型,可以在<>里面使用extends,其实也就是泛型的协变跟逆变,但是在Dart中木有super限制,如下:

与Java的区别:

  • Java中的泛型信息是编译时的,泛型信息在运行时是不存在的。
  • Dart的泛型类型是固化的,在运行时也有可以判断的具体类型。

如何理解?看程序:

也就是说在Java中,可以测试对象是否为List,但无法测试它是否是List<String>。

库:

使用核心库:

  • import 后的必须参数为库 的 URI。(Uniform Resource Identifier统一资源标识符)
  • 对于内置的库,URI 使用特殊的 dart: scheme。
  • 对于其他的库,你可以使用文件系统路径或者 package: scheme。

载入三方库:

pubspec.yaml声明需要引用的库,使用Packages get进行拉取。

那咱们来找一个三方库来使用一下,先上官网搜一下三方库:

所以咱们将其依赖添加至咱们的工程:

添加完依赖之后,就可以使用了,如下:

载入文件:

如何来引用咱们自己的Dart文件呢?下面新建待引用的Dart文件:

然后引用一下:

指定库前缀:

如果两个库有冲突的标识符,可以为其中一个或两个库都指定前缀,比如:MyLib1.dart 和 MyLib2.dart 都有一个名字为 MyLib 的类, 此时解决冲突就可以指定前缀来解决,如下:

选择性载入:

如果只使用库的一部分功能,则可以选择需要导入的内容。

下面来演示一下:

这功能还挺灵活的。。

延迟载入:

  • 使用 await 关键字暂停代码执行一直到库加载完成。
  • 可提高程序启动速度。
  • 用在不常使用的功能。
  • 用在载入时间过长的包。
  • 执行 A/B 测试,例如 尝试各种算法的 不同实现。

下面来使用一下,我们在请求完数据之后再来加载文件:

看下结果:

感觉Dart好强大呀,值得一学!!!

自定义库:

  • part 可以把一个库分开到多个 Dart 文件中。
  • 或者我们想让某一些库共享它们的私有对象的时候,可以需要使用part。
  • import不会完全共享作用域,而part之间是完全共享的。如果说在A库中import了B库,B库import了C库,A库是没有办法直接使用C库的对象的。而B,C若是A的part,那么三者共享所有对象。并且包含所有导入。

啥意思,比如说有三个Dart文件:

而mylib.dart利用part整合了tool.dart和util.dart文件的功能,最终我们使用时只要引用mylib则可以拥有三个文件的功能,如下:

咱们来试一下:

运行:

Fluter基础巩固之Dart语言详解<二>的更多相关文章

  1. Fluter基础巩固之Dart语言详解<一>

    在上一篇https://www.cnblogs.com/webor2006/p/11367345.html中咱们已经搭建好了Flutter的开发环境了,而Flutter的开发语言是选用的dart,那么 ...

  2. Fluter基础巩固之Dart语言详解<三>

    继续Dart语言的学习,这次过后下次就进入全新的Flutter的学习了,小小的激动.. 操作符重载: C++中也有,咱们来看一下在Dart中是如何来实现的: 比较简单. 异步[重要!]: async和 ...

  3. 基础 | batchnorm原理及代码详解

    https://blog.csdn.net/qq_25737169/article/details/79048516 https://www.cnblogs.com/bonelee/p/8528722 ...

  4. Java工程师 基础+实战 完整路线图(详解版)

    Java工程师 基础+实战 完整路线图(详解版)   Java 基础 Java 是一门纯粹的面向对象的编程语言,所以除了基础语法之外,必须得弄懂它的 oop 特性:封装.继承.多态.此外还有泛型.反射 ...

  5. Docker 基础技术之 Linux cgroups 详解

    PS:欢迎大家关注我的公众号:aCloudDeveloper,专注技术分享,努力打造干货分享平台,二维码在文末可以扫,谢谢大家. 推荐大家到公众号阅读,那里阅读体验更好,也沉淀了很多篇干货. 前面两篇 ...

  6. 原来Github上的README.md文件这么有意思——Markdown语言详解(sublime text2 版本)

    一直想学习 Markdown 语言,想起以前读的一篇 赵凯强 的 博客 <原来Github上的README.md文件这么有意思——Markdown语言详解>,该篇博主 使用的是Mac系统, ...

  7. 《Java基础——break与continue用法详解》

    Java基础--break与continue用法详解       1. break语句: 规则: 1. 仅用于循环语句和switch语句当中,用于跳出循环. 2. 当只有一层循环时,则直接跳出循环,不 ...

  8. JavaEE基础(03):Http请求详解,握手挥手流程简介

    本文源码:GitHub·点这里 || GitEE·点这里 一.Http协议简介 1.概念说明 HTTP超文本传输协议,是用于从万维网服务器传输超文本到本地浏览器的传送协议,基于TCP/IP通信协议来传 ...

  9. Java基础篇(JVM)——字节码详解

    这是Java基础篇(JVM)的第一篇文章,本来想先说说Java类加载机制的,后来想想,JVM的作用是加载编译器编译好的字节码,并解释成机器码,那么首先应该了解字节码,然后再谈加载字节码的类加载机制似乎 ...

随机推荐

  1. B1001 害死人不偿命的(3n+1)猜想 (15 分)

    一.参考代码: #include<iostream> using namespace std; int main(){ int n; int step = 0; cin >> ...

  2. CF1217E Sum Queries? (线段树)

    完了,前几天才说 edu 的 DEF 都不会,现在打脸了吧 qwq 其实在刚说完这句话 1min 就会了 D,3min 就会了 E 发现,对于大小 \(\ge 3\) 的不平衡集合,它至少有一个大小为 ...

  3. [LeetCode] 287. Find the Duplicate Number 寻找重复数

    Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), pro ...

  4. [LeetCode] 137. Single Number II 单独的数字之二

    Given a non-empty array of integers, every element appears three times except for one, which appears ...

  5. C语言I作业12—学期总结

    一.我学到的内容 二我的收获 作业 收获 C语言博客作业1 刚开始初步了解C语言方面的知识 学会Markdown基本语法 C语言博客作业2 学会了应该如何提问 PTA系统常见问题解答 学会了MinGW ...

  6. JavaScript 系列--JavaScript一些奇淫技巧的实现方法(二)数字格式化 1234567890转1,234,567,890;argruments 对象(类数组)转换成数组

    一.前言 之前写了一篇文章:JavaScript 系列--JavaScript一些奇淫技巧的实现方法(一)简短的sleep函数,获取时间戳 https://www.mwcxs.top/page/746 ...

  7. HTML连载29-div和span标签

    一.div标签 1.作用:一般用于配合CSS完成网页的基本布局 2.例子: <style> .head{ width: 980px; height: 100px; background: ...

  8. linux-centos安装图解及配置IP远程连接

    本次安装使用vm软件的15版本,系统为centos7.6(1810) 系统安装图解>配置IP信息联网>真实机是无线网络状态,虚拟机如何联网>远程工具连接虚拟机 一,vm安装cento ...

  9. mgcp的alg功能实现

    刚吃了一碗还算正宗的潮汕牛筋丸粿条和一颗卤蛋,算是给自己的生日礼物. 这一周工作只围绕了一个主题“mgcp的alg功能实现”. 1. 应用场景: 一台运行mgcp语音协议的终端设备,经过一台路由器到达 ...

  10. ant-design-pro引用css

    ant-design-pro中默认只能引用less文件,引用了css文件也是无效的.所以需要在配置文件config.js中找到  cssLoaderOptions,在 getLocalIdent中加入 ...