一. OOP 语言
一般都有一个终极父类 Object,一切对象若是没有赋值都默认 null/nil
dart 中即使变量是数字类型默认值也是 null,因为在 Dart 中一切都是对象,数字类型 也不例外。函数也是对象。
二. 变量类型
- 整数(int)
- 小数(float、double、Number)
- 布尔值(Bool)
- 字符串(String)
- 有序数组(List、Array 等)
- 无序数组(Set 等)
- 键值类型(Dictionary、hash、map) ....
final表示变量只能被赋值一次;const表示变量是编译时常量,const变量默认为final变量。 字符串是由单引号或双引号包裹的字符序列, 布尔类型只包含两个对象,true和false。
三. 函数
1. 函数声明由返回值(可选)、函数名、参数列表以及函数体构成。函数体中可以继续声明函数,即局部函数。
//函数一般形式如下:
(返回值) + 函数名 + 参数列表 + (返回值){
//goes
}
//函数参数列表形式一般如下:
{形参, 形参, …}
{形参 实参 , 形参 实参, …}
{实参 形参 , 实参 形参, …}
2. 函数一般分类:
(1)顶级函数:不为类、结构体服务的函数,在其外部例如 main 函数。
(2)匿名函数:没有名字的函数,这种函数被称为 匿名函数, 有时候也被称为 lambda 或者 closure 。 匿名函数可以赋值到一个变量中。
闭包(closure)是指一个函数对象,即使不在初始作用域内,也仍然能够访问其中的变量。一般是花括号括起来的代码块。 所谓闭包,即是函数中包含函数,这里的函数我们可以包含(Lambda表达式,匿名函数,局部函数,对象表达式)。函数式编程是现在和未来良好的一种编程趋势。 闭包表达式总是被大括号括着 其参数(如果存在)在 -> 之前声明(参数类型可以省略) 函数体(如果存在)在 -> 后面。
(3)高阶函数即指:将函数用作一个函数的参数或者返回值的函数。
(4)构造函数用于将类进行实例化(即创建对象),大部分语言需要配合关键字new。
3. 函数词法作用域(也称为静态作用域),即变量的作用域在定义时确定。
作用域范围由变量所处代码块(大括号)的层级决定,层级越深,作用域越小,层级越浅,作用域越大。
4. 函数返回值:函数若是一等公民,它可以存储在变量中,可以作为参数传递,可以在顶层声明。如果函数体内没有return语句,则语句return null(void)。
四. 运算符
- 算术运算符
- 关系运算符
- 类型判定运算符
- 赋值运算符
- 逻辑运算符
- 按位和移位运算符
- 条件表达式)
- 其他运算符
一般都是约定俗成,通用的,学习新语言只需要关注语言新增的,或者和通用逻辑有出入的部分
五. 控制流程语句
- if 和 else
- for 循环(、 for-in)
- while 和 do-while
- break 和 continue
- switch 和 case
- assert
一般都是约定俗成,通用的,学习新语言只需要关注语言新增的,或者和通用逻辑有出入的部分
六: 类
1. OOP 语言的每个对象都是一个类的实例,所有的类都继承于 Object;(类是对象的模板,用于创建对象。类的声明是使用关键字class,所有类都直接或间接继承最顶端的Object类。)需要特别注意基础数据类型是否是对象。
特殊:Dart中任何保存在变量中的都是一个对象, 并且所有的对象都是对应一个类的实例。 无论是数字,函数和 null 都是对象。所有对象继承自 Object 类。
2. 类的变量和方法
(方法是为对象提供行为的函数。) 类中可以声明数据和函数,即对象的属性和方法。方法的调用要通过对象来完成: 调用的方法可以访问其对象的其他函数和数据。 普通的属性和方法是与对象实例绑定,它们被称之为实例变量和实例方法。 使用static修饰的属性和方法,它们与类绑定,通常称为类(静态)变量和类(静态)方法。
实例变量和实例方法、类变量和类方法,在类中都可以通过名称直接访问,实例变量和实例方法还可以通过self/this访问;在类的外部,实例变量和方法是通过实例.变量方式进行访问,而类变量和类方法必须通过类名.变量方式才能访问。
实例变量有时称为字段或属性。 方法是为对象提供行为的函数。 顶级函数/变量是指不在类或者结构体之内的函数。对于常见或广泛使用的工具和函数, 应该考虑使用顶级函数而不是静态方法。
3. 构造函数用于将类进行实例化(即创建对象),大部分语言需要配合关键字new。
4. Getter/Setter 方法(大部分语言自动实现或者需要手动实现),它们虽是方法却有跟属性一样的访问方式(oc/swift/dart/java等)。
5. 抽象类和抽象方法,没有函数体的方法,即只声明而不实现的方法被称为抽象方法,它只能出现在抽象类中。抽象类是使用abstract关键字修饰的类,它可以包含非抽象方法,可以被继承但不能被实例化。 如果希望抽象类能够被实例化,那么可以通过定义一个 工厂构造函数来实现。
6. 类(继承)
//一般形式(* 可以为 :、extends ...)
class ChildClass * FatherClass {
}
7. 为类添加功能
//分类,Mixin 等根据语言而不同:
OC: 分类(Category)
Swift: 类扩展(extension)和协议
Dart: Mixin
...
mixin是一种特殊的专门用于复用的类,通过mixin可以实现类似于多继承的效果。Dart 中 mixin 有两种书写方式,一种是使用class声明一个没有父类和构造函数的类,另一种是直接使用mixin关键字。
七:泛型
通常情况下,使用一个字母来代表类型参数, 例如 E, T, S, K, 和 V 等。配合<>使用。 在类型安全上通常需要泛型支持, 它的好处不仅仅是保证代码的正常运行: 正确指定泛型类型可以提高代码质量。 使用泛型可以减少重复的代码。
abstract class Cache<T> {
T getByKey(String key);
void setByKey(String key, T value);
}
//限制泛型类型
class Foo<T extends SomeBaseClass> {
八:同步异步 sync/async
不同语言的实现没有约定俗成的做法,不过找这两个关键字准没错。
Swift 的 async 简单例子:
DispatchQueue.global().async {
DDLog("耗时操作 \(Thread.current)")
//主队列回调
DispatchQueue.main.async {
DDLog("主线程更新 UI \(Thread.current)")
}
}
Objective-C 的 async 简单例子:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
DDLog("耗时操作 \(Thread.current)")
dispatch_async(dispatch_get_main_queue(), ^{
DDLog("主线程更新 UI \(Thread.current)")
});
});
Dart 的 async 简单例子:
使用 Future 或 Stream 对象的函数. 这些函数在设置完耗时任务(例如 I/O 曹组)后, 就立即返回了,不会等待耗任务完成。 使用 async 和 await 关键字实现异步编程。
Future checkVersion() async {
var version = await lookUpVersion();
// Do something with version
}
用技术术语来讲,如果一段代码定义的是如何做一件事的步骤,我们称之为命令式;相反,如果定义的是我们所预期的最终结果,它就是声明式。命令式编程强调精确控制过程细节;而声明式编程强调通过意图输出结果整体。
待续...