1、开发准备
1.1 Dart 中文官网
1.2 Win10下环境搭建
1.2.1 如果安装了Flutter-SDK,其实也可以直接使用里面的dart - sdk
image.png image.png1.2.2 如果之前没有安装 Flutter-SDK,请看如下步骤(在线方式)
安装 包管理器 chocolatey
- 点击右下级角的开始按钮,输入 cmd ,选择以管理员权限运行
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.pngimage.png
image.png
离线方式
-
查看跟IDEA对应的插件版本
image.png -
去插件官网查找对应的版本
https://plugins.jetbrains.com/plugin/6351-dart/versions
image.png1.5 项目创建
image.png image.png- 运行出现报错:Setting VM flags failed: Unrecognized flags: checked
-
把 Checked mode 勾取消即可
image.png
2、数据类型
2.1 变量与常量
变量
-
使用var声明变量,可赋予不同类型的值
-
未初始化时,默认值为null
-
使用fianl声明一个只能赋值一次的变量
常量
-
使用const声明常量
-
使用const声明的必须是编译期常量
-
const 与 final有着本质的区别
1)在定义const常量时,你必须直接赋一个字面量,而不能是一个变量或者公式;
2)在定义final常量时,如何赋值就无所谓了,但赋值后就不能再改了
2.2 内置类型
2.2.1 数值型-Number
-
Int 整型
-
double 浮点型
数值型操作
- 运算符: +、 -、 *、 /、 ~/、 %
- 常用属性:isNaN、 isEven、 isOdd等
image.png
-
常用方法:abs()、round()、floor()、ceil()、toInt()、toDouble()
image.png
2.2.2 字符串-String
字符串创建
-
使用单引号,双引号创建字符串
-
使用三个引号或双引号创建多行字符串
-
使用r创建原始raw字符串
2.2.3 布尔型-Boolean
-
使用bool表示布尔类型
-
布尔值只有true 和 false
2.2.4 列表-List
创建
- 创建List: var list = [1,2,3];
- 创建不可变的List:var list = const [1,2,3];
- 构造创建: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
- 创建
- 创建Map
var language = {"first":"Dart", "second" : "java"};
- 创建不可变Map
var language = const {"first":"Dart", "second" : "java"};
- 构造创建
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.png3、运算符
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跳转标签
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<String,Logger> _cache = <String,Logger>{};
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实现
}
网友评论