变量和常量
变量
- var声明 可以赋值给不同类型
- 未初始化时默认为null
- 使用final关键字声明一个只能赋值一次的变量
var a // null
a= 10 // 10
a=hello'' // hello
final b = 'jack'
常量
- const 声明
- 编译期常量(编译器就能)
内置类型
- 数值型 Number
- Int
- Double
num a = 10
a = 12.5
int b = 123
double c =12.1
运算符
+ - * / ~/ %
常用属性
isNaN isEven isOdd等
方法
abs()
floor()
....
- 字符串 String
定义
- 单双引号 创建字符串
- 三个引号或双引号创建多行字符串
- 使用r创建原始raw字符串
String str1 = 'hello'
string str2 = ''' Hello
Dart '''
string str3 = "Hello \n Dart" //会换行
string str4 = r"Hello \n Drat" // 原样输出
常用操作
- 运算符 + * == []
- 插值表达式 ${} 和es6中的一样
- 常用属性 length isEmpty isNotEmpty
- 常用方法: contains(), subString(),startWith(),endWith(), indexOf(), lastIndexOf(), toLowCase(), toUpperCase(),trim(),trimLeft(),trimRight(), split(), replaceXXX()
+ : 连接字符串
* : 重复几次
==: 是否相等
[]: 取出对应下标的字符
- 波尔 Boolean
- 列表 List(数组)
定义
var list = [1,2,3]
var list = const [1,2,2] // 不可变List
var list = new List()
常用操作
[], length
add(),insert()
remove(),clear()
indexOf(), lastIndexOf()
sort(),sublist()
shuffle(), asMap() , forEach()
- 键值对 Map
定义
var map = {"a": 1, "b": 2}
var map = const {"a": 1, "b": 2}
var map = new Map()
常用操作
[], length
isEmpty, isNotEmpty
Keys, values
containsKeys, containsValue
remove
forEach
- dynamic
动态类型 所以可以被修改的都是动态类型 也可以用dynamic关键字直接声明
- Runes
- Symbols
运算符
基本运算符和其他语言的相同
- 赋值运算符 ??= 如果定义的值本身为空的话赋值,否则不赋值
var a = 0
var b
a ?? = 1
b ?? = 1
print(a) ==> 0
print(b) ==> 1
- 条件表达式 ??
var a
var b = 'jack'
var c = a ?? b
print(c) => jack a本身有值的话就用本身的,没值就将b的赋值过来
switch case
- 比较类型 num string 编译常量 对象 枚举
- continue 跳转标签
方法
- 方法也是对象 具体的类型是Function
- 返回值类型,参数类型都可以省略
- 箭头语法 => 是 {return xxx}的缩写 只适用于一个表达式的情况
- 方法都有返回值 如果没有 默认 return null
String getPerson (String name, Int age) {
return "name = $name, age = $age"
}
Function getPerson ( name, age) {
return "name = $name, age = $age"
}
getPerson ( name, age) => "name = $name, age = $age"
可选参数
- 可选命名参数 {param1, param2}
- 可选位置参数 [param1, param2]
- 可选参数 要在具体参数后面
printPer (String name, {int age, string sex}) {
print("name=$name, age=$age, sex=$sex")
}
// 可以按照名称
printPer ('jack', age: 12)
=> name=jack, age=12, sex = null
printPer2 (String name, [int age, string sex]) {
print("name=$name, age=$age, sex=$sex")
}
// 直接按照位置来传
printPer ('jack', 12)
=> name=jack, age=12, sex = null
默认参数
- 使用 =
printPer (String name, [int age, string sex = '男']) {
print("name=$name, age=$age, sex=$sex")
}
printPer ('jack', age: 12)
=> name=jack, age=12, sex = 男
匿名方法
() {}
// 赋值给变量来调用
var func = () {}
// 直接调用
((){
print('123')
})()
闭包
定义在方法中的方法,可以获取外层方法的局部变量
void main (){
var func = a()
a() ==> 0
a() ==> 1
a() ==> 2
a() ==> 3
想要获得count的值只能通过闭包返回的, 无法通过点语法什么的获取
}
a () {
int count = 0;
return () {
print(count++)
}
}
面向对象
类的创建
- class 关键字创建
- new 来实例化 new可以省略
属性和方法
- 默认生成setter getter方法
- final声明的属性只有getter方法
- 属性和方法通过 . 访问
- 方法不能被重载
类及成员的可见性
- Dart中的可见性以library(库)为单位
- 默认情况下,一个dart文件就是一个库
- 使用_表示库的私有性
- 使用import导入库
class Person {
String name;
Intager _age;
void () {
print ('name=$name, age=_age')
}
}
var person = new Person()
person.name = 'jack'
!!! person._age = 10 //私有不能赋值
计算属性
- 计算属性的值通过计算而来,本身不存储
- 计算属性赋值,其实是通过计算转换到其他实例变量
class Rectangle {
num wid, height;
num get area => wid * height // 这是一个属性, 通过其他属性计算而来
set (value) {
width = value / 20
height = 20
}
}
构造方法
- 如果没有自定义构造方法,则会有个默认构造方法
- 如果存在自定义构造方法 默认构造方法将失效
- 构造方法不能重载
class Person {
string name
int age
final string sex
/**
* 这里 使用this的语法糖可以对final类型赋值
* 但是写在构造方法中就不行了,因为执行在构造方法之前
*/
Person (string name ,this.age ,this.sex) { // 第二种是语法糖,
this.name = name
print(age)
}
}
var per = new Person('jack', 20)
命名构造方法
- 使用命名构造方法 可以实现多个构造方法
- 使用 类名.方法 的形式实现
class Person {
string name
int age
final string sex
Person (string name ,this.age ,this.sex) { // 第二种是语法糖,
this.name = name
print(age)
}
Person.withName(string name) {
this.name = name
}
}
<!-- 多个构造方法 类似oc -->
new Person('jack', 12, 'man')
new Person.withName('marry')
常量构造方法
- 如果类是不可变的状态,可以把对象定义成编译时常量
- 使用const声明构造方法并且所有的变量都为final
- 使用const 声明对象 可以省略
class Person {
final string name
final int age
final string sex
/**
* 这里 使用this的语法糖可以对final类型赋值
* 但是写在构造方法中就不行了,因为执行在构造方法之前
*/
const Person (this.name ,this.age ,this.sex)
}
Person per = const Person('jack', 20, 'nan')
Person per2 = Person('mary', 20, 'nv')
工厂构造方法
- 类似设计模式中的工厂模式
- 在构造方法💰加 factory实现工厂构造方法
- 工厂构造方法可返回对象
初始化列表
- 初始化列表会在构造方法体之前执行
- 使用逗号分割初始化表达式
- 初始化列表常用语于设置final变量的值
class Person {
final string name
final int age
final string sex
Person (Map map): name = map['name'] ,age=map['age'] ,sex=map['sex'] {
}
}
静态成员
- 使用static关键字实现类级别的变量和函数
- 静态成员不能访问非静态成员 反之可
- 类中的常量需要用static const声明
对象操作符
- ?. 条件成员访问
- as 类型转换
- is is! 是否指定类型
- .. 级联操作
1.
var per = new Person()
per.?name = 'jack' //
2.
var per1 = ''
per1 = new Person() // 此时per仍为动态类型
(per1 as Person) // 此时为Person类
4.
var per2 = new Person()
per2..name="tom"..age="12"..work()
对象的call方法
- 如果类实现了call方法,那么该类的对象可以作为方法使用
class Person {
String name
Int age
String call() {
return "name= $name, age=$age"
}
}
Person per = new Person()
per() => name= $name, age=$age
面向对象拓展
继承
- 单继承 多态性
- 使用extends继承一个类
- 子类可以重写父类的方法 setter 和getter
- 子类会继承父类可见的属性和方法 不会继承构造方法
继承中的构造方法
- 子类的构造方法默认调用父类无名无参的构造方法
- 如果父类没有无名无参的构造方法,则需要显示调用父类构造方法
- 在构造方法之后使用:显示调用父类构造方法
class Person {
String name
Person(this.name) //无名有参
Person.withName(this.name) // 有名有参
}
class Children {
Student(String name): super.withName(name)
}
执行顺序
初始化列表>父类构造方法>子类构造方法
抽象类
- 使用abstract 不能直接被实例化
- 抽象方法前不用谢 abstract
- 抽象类可以没有抽象方法
- 抽象方法不能没有抽象类
接口
- 类和接口是统一的 类即接口
- 需要重写所有属性和方法
- 使用implement
- 建议使用抽象类作为接口
- 每个类都隐式的定义了一个包含所有实例成员的接口
- 如果是复用已有类的实现 使用继承extends
- 如果只是使用已有类的行为 使用implement
Mixins
1.Minxins 类似多继承 ,是在多类继承中重用代码的一个方式
class Student extends Techer1 with Teacher2, Teacher3 {
// 如果Teacher2, Teacher3 有相同的方法 后者覆盖前者
}
还可以写成
class Student = Techer1 with Teacher2, Teacher3;
- 作为Mixins的类不能有显示的构造方法
- 作为Mixins的类只能继承自Object(不能继承别的类)
操作符复写
- 复写操作符需要在类中定义
返回类型 operator 操作符(参数1,参数2) {
实现体...
return 返回值
}
- 如果复写 == 还需要复写对象的hasCode,getter方法
枚举
- 有穷数列集的数据类型
- 使用关键字enum定义
- 常用语代替常量 控制语句
泛型
class Utils <T>{
T element; //
void put (T element) {
this.element = element
}
void out<Z> (Z element) {
prirnt (element)
}
}
var utils = new Utils<String>()
utils.put('element')
utils.out<Int>(1)
网友评论