文档地址
类与对象
使用 关键字 class 声明一个类;
使用 关键字 new 创建一个对象, new 可以省略;
所有对象都继承于 Object 类;
构造方法
如果没有自定义构造方法,则会有个默认构造 方法, 并且该构造函数会 调用其父类 的无参数构造方法;
如果存在自定义构造方法,则 默认构造方法无效;
构造方法不能重载(不能存在同名的构造方法);
子类不会继承父类的构造函数,如果子类没有声明构造函数,那么只会有一个默认无参数的构造函数。
注意: 所有未初始化的实例变量其值均为 null;
使用 命名构造方法,可以实现多个构造方法;
使用 类名. 方法 的形式实现
常量构造函数
一些类提供了 常量构造函数。使用常量构造函数,在构造函数名之前加 const 关键字,来创建编译时常量时,两个使用 相同构造函数 相同参数值 构造的编译时常量是同一个对象:
计算属性
计算属性的值是通过计算而来,本身不存储值;
计算属性赋值,其实是通过计算转换到其他实例变量;
调用父类非默认构造函数
子类的构造函数会调用父类的匿名无参数构造方法,并且该调用会在子类构造函数的函数体代码执行前,如果子类构造函数还有一个 初始化列表,那么该初始化列表会在调用父类的该构造函数之前被执行,总的来说,这三者的调用顺序如下(重要):
1 初始化列表;
2 父类的无参数构造函数;
3 当前类的构造函数;
如果 父类没有匿名无参数构造函数,那么子类必须调用父类的其中一个构造函数,为子类的构造函数 指定一个父类的构造函数 只需在构造函数体前使用(:)指定。
初始化列表
除了 调用父类构造函数 之外,还可以在 构造函数体执行之前 初始化实例变量。每个实例变量之间使用 逗号 分隔;
注意:初始化列表会在构造方法体执行 之前 执行,初始化列表表达式 = 右边的语句 不能使用 this 关键字。
初始化列表常 用于设置 final 变量的值 (跟语法糖作用一样);
重定向构造函数
有时候类中的构造函数仅用于 调用类中其它的构造函数,此时该构造函数没有函数体,只需在函数签名后使用(:)指定需要重定向到的其它构造函数 (使用 this 而非类名):
常量构造函数
如果类生成的对象都是不变的,可以在生成这些对象时就将其变为编译时常量。你可以在类的构造函数前加上 const 关键字并确保所有 实例变量 均为 final 来实现该功能;
工厂构造函数
工厂构造方法类似于设计模式中的工厂模式;
在构造方法前添加 关键字 factory 实现 一个工厂构造方法,这将意味着使用该构造函数构造类的实例时 并非总是会返回 新的实例对象;
例如,工厂构造函数可能会从缓存中返回一个实例,或者返回一个子类型的实例;
在工厂构造方法中 可返回对象;
注意: 在工厂构造函数中无法访问 this!
Logger 的工厂构造函数从缓存中返回对象,和 Logger.fromJson 工厂构造函数从 JSON 对象中初始化一个最终变量;
静态成员
使用 关键字 static 来实现 类级别 的变量和函数;
静态成员 不能访问 非静态成员,非静态成员可以访问静态成员;
1. 静态变量
静态变量(即类变量)常用于声明类范围内所属的状态变量和常量:
类中的常量需要使用 static const 声明;
2. 静态方法
静态方法(即类方法)不能对实例进行操作,因此 不能使用 this。但是他们可以访问静态变量;
对象操作符
条件成员访问:?. // ?前面不为空就接着执行, 为空就不执行. 后面得
类型转换 : as
是否指定类型: is , is! // 有点像 instanceof
级联模式: ..
操作符复写(运算符的重载)
复写操作符需要在类中定义
返回类型 operator 操作符 (参数1, 参数2, ....){
// 实现code
return 返回值
}
注意:如果覆写 ==, 还需要覆写对象的 hashCode getter 方法;
可覆写的操作符
< 、+、|、[]、>、/、^、[]=、 <=、~/、&、~、>=、*、<<、==、-、%、>>
对象 call 方法 (还是不建议使用)
如果类实现了 call() 方法 , 则 该类的对象 可以作为 方法 使用;
Getter 和 Setter
Getter 和 Setter 是一对用来读写对象属性的特殊方法,上面说过实例对象的每一个属性都有一个隐式的 Getter 方法,如果为非 final 属性的话还会有一个 Setter 方法,你可以使用 get 和 set 关键字为额外的属性添加 Getter 和 Setter 方法:
面向对象扩展
继承
使用 关键字 extends 继承一个类,并可使用 关键字 super 引用一个父类;
子类会继承父类可见的属性 和方法,不会继承构造方法;
子类可以重写父类的实例方法(包括操作符)、 Getter 以及 Setter 方法。你可以使用 @override 注解来表示你重写了一个成员;
单继承, 多态性
抽象类(像其他语言的接口)
抽象类使用 关键字 abstract 表示 ,不能直接被实例化;
抽象方法不用 abstract 装饰, 无实现;
抽象类 可以 没有抽象方法;
有抽象方法的类一定得声明为抽象类;
抽象类常用于声明接口方法(重要)、有时也会有具体的方法实现;
接口 (和其他语言接口不同)
类和接口是统一的, 类就是接口;
每个类都隐式的定义了一个包含所有实例成员的接口;
如果是复用已有类的实现,使用继承(extends) (因为接口都是要重写属性和方法);
如果只是使用已有类得外在行为,使用接口(implements);
如果需要实现多个类接口,可以使用逗号分割每个接口类:
class Point implements Comparable, Location {...}
注意: 推荐 使用 抽象类的形式作为接口;
Mixin (重要)
1 Mixins 类似于多继承, 是在多类继承中重用一个类代码的方式;
使用 with 关键字并在其后跟上 Mixin 类的名字来使用 Mixin 模式:
2 作为 Mixin的类 不能有显示声明构造方法, 比如:
3 作为 Mixin 的类,只能继承子 Object, 比如 A,B, C 不能extends 其他类
4 使用关键字 with 连接 一个或多个 mixin
A,B,C,D 四个类
class D extends A with B, C { }
简写 class D = A with B , C, 此写法适合 D 中没有自己的属性和方法
如果方法 A, B, C 中方法同名,调用最后一个继承的 方法,上面就是 调用C中的方法;
注意:请记住 想要实现一个 Mixin,请创建一个继承自 Object 且 未声明构造函数的类!
枚举类型
index 从0 开始, 依次累加
不能指定原始值;
不能添加方法;
枚举不能成为子类,也不可以 mix in,你也不可以实现一个枚举;
不能显式地实例化一个枚举类;
每一个枚举值都有一个名为 index 成员变量的 Getter 方法
enum Color { red, green, blue }
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);
使用枚举类的 values 方法获取全部的枚举值
List
colors = Color.values; assert(colors[2] == Color.blue);
泛型
泛型的作用:
泛型常用于需要要求类型安全的情况,但是它也会对代码运行有好处:
1. 适当地指定泛型可以更好地帮助代码生成;
2. 使用泛型可以减少代码重复。
泛型的使用
1 泛型类
2 泛型方法
方法 first
函数的返回值类型 (T);
参数的类型 (List
局部变量的类型 (T tmp);
限制参数化类型
子类限制继承 Object :
规定了要使用 SomeBaseClass 或者它的子类来作为泛型参数: