Fluter基础巩固之Dart语言详解<二>
继续学习枯燥的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语言详解<二>的更多相关文章
- Fluter基础巩固之Dart语言详解<一>
在上一篇https://www.cnblogs.com/webor2006/p/11367345.html中咱们已经搭建好了Flutter的开发环境了,而Flutter的开发语言是选用的dart,那么 ...
- Fluter基础巩固之Dart语言详解<三>
继续Dart语言的学习,这次过后下次就进入全新的Flutter的学习了,小小的激动.. 操作符重载: C++中也有,咱们来看一下在Dart中是如何来实现的: 比较简单. 异步[重要!]: async和 ...
- 基础 | batchnorm原理及代码详解
https://blog.csdn.net/qq_25737169/article/details/79048516 https://www.cnblogs.com/bonelee/p/8528722 ...
- Java工程师 基础+实战 完整路线图(详解版)
Java工程师 基础+实战 完整路线图(详解版) Java 基础 Java 是一门纯粹的面向对象的编程语言,所以除了基础语法之外,必须得弄懂它的 oop 特性:封装.继承.多态.此外还有泛型.反射 ...
- Docker 基础技术之 Linux cgroups 详解
PS:欢迎大家关注我的公众号:aCloudDeveloper,专注技术分享,努力打造干货分享平台,二维码在文末可以扫,谢谢大家. 推荐大家到公众号阅读,那里阅读体验更好,也沉淀了很多篇干货. 前面两篇 ...
- 原来Github上的README.md文件这么有意思——Markdown语言详解(sublime text2 版本)
一直想学习 Markdown 语言,想起以前读的一篇 赵凯强 的 博客 <原来Github上的README.md文件这么有意思——Markdown语言详解>,该篇博主 使用的是Mac系统, ...
- 《Java基础——break与continue用法详解》
Java基础--break与continue用法详解 1. break语句: 规则: 1. 仅用于循环语句和switch语句当中,用于跳出循环. 2. 当只有一层循环时,则直接跳出循环,不 ...
- JavaEE基础(03):Http请求详解,握手挥手流程简介
本文源码:GitHub·点这里 || GitEE·点这里 一.Http协议简介 1.概念说明 HTTP超文本传输协议,是用于从万维网服务器传输超文本到本地浏览器的传送协议,基于TCP/IP通信协议来传 ...
- Java基础篇(JVM)——字节码详解
这是Java基础篇(JVM)的第一篇文章,本来想先说说Java类加载机制的,后来想想,JVM的作用是加载编译器编译好的字节码,并解释成机器码,那么首先应该了解字节码,然后再谈加载字节码的类加载机制似乎 ...
随机推荐
- MacbookPro升级10.15 Catalina之后无法读写NTFS
冲着Sidecar的双屏功能,乐呵呵的跑去升级了10.15,结果就悲剧了. 所有移动硬盘和U盘都写不了,无奈只好上网找办法,目前找到一个便宜的方法: 共2步: Step 1:编写fstab文件 使用T ...
- [LeetCode] 152. Maximum Product Subarray 求最大子数组乘积
Given an integer array nums, find the contiguous subarray within an array (containing at least one n ...
- 仅逗oier们一笑(不定期更新中)(update.2019年12月8日)
CCF的正确解释: //部分来自:朝阳的二愣子的CSDN博客.ydclyq 的博客 .拱垲的博客.Randolph's Blog. 编译下列程序,会有意想不到的惊喜哦(注意打开声音): #includ ...
- SpringCloud微服务实现生产者消费者以及ribbon负载均衡
一.SpringCloud_eureka_server 1.导入依赖 <dependencies> <dependency> <groupId>junit</ ...
- okhttp 发送get post 请求
package com.qlwb.business.util; import java.util.Map; import com.alibaba.fastjson.JSON; import okhtt ...
- Salesforce 开发新工具 - Visual Studio Code
最近尝试使用Visual Studio Code来做Salesforce的开发工具,体验上比Sublime好用不少,介绍下详细步骤 第一步:下载对应版本的Visual Studio Code 下载地址 ...
- PowerShell的异常处理办法
$ErrorActionPreference = 'Stop' Try{ # C:\xxx 不存在 Copy-Item C:\xxx -ErrorAction Stop } Catch ...
- centos7上配置mysql8的主从复制
注意:1.主库:10.1.131.75,从库:10.1.131.762.server-id必须是纯数字,并且主从两个server-id在局域网内要唯一. [主节点]vi /etc/my.cnf[mys ...
- for循环居然还可以这样写
公司代码有点坑,查找问题,发现for循环的写法不是固定条件在中间,写反了也是可以运行的.比如:下面一个简单的for循环 int m=0; for(int i=0;i>3;i++){ m=m+i; ...
- RabbitMQ实例C#
驱动组件.NET版本 官网推荐驱动:RabbitMQ.Client https://www.rabbitmq.com/devtools.html#dotnet-dev Connection和Chann ...