对象的生命周期 另一个类与结构体的不同是类可以被子类化。 雷和结构体都可以被拓展,并且实现protocol,但是只用类可以继承其他类。 01 | class Pineapple : Apple { |
08 | convenience init(ripe: Bool) { |
17 | println( "Pineapple down" ) |
19 | override func description() -> String { |
20 | return "pine" + super.description() |
22 | override func enripen() { |
就像你看到的,Swift为继承添加了一点更有趣的需要学习的东西。对于初学者来说,你需要清除你覆盖父类中某个方法的意图。如果你想阻止子类覆盖一些东西,你可以在一个单独声明或整个类的前面加上@final属性。阅读 Apple’s documentation了解更多。
初始化 Swift的对象分两步进行初始化: 首先对象必须是有效的,然后它能被替换。 03 | init(foot_size: Double) { |
05 | addGrowthCompensation() |
07 | func addGrowthCompensation() { |
使对象有效必须要调用一个超级类指定的init()方法。类可以同时拥有指定的以及便捷的(用关键词'convenience'标记)初始化方法。便捷初始化方法调用同一个类中的其他初始化方法(最终还是一个指定的初始化方法),而指定的初始化方法调用超级类的初始化方法。 如果你给所有的超级类指定初始化方法添加初始化方法,你的类也会自动继承所有便捷初始化方法。如果没有添加任何指定的初始化方法,你的类则继承超级类的所有(指定的和便捷的)初始化方法。 深入阅读请参见Initialization。
类型转换 类之间的转换,特别是向下转换,你可以使用"is","as?"和"as"关键词: 01 | let apple: Apple = Pineapple() |
03 | let exotic: Bool = apple is Pineapple |
05 | let pineappleOption: Pineapple? = apple as? Pineapple |
06 | let pineapple: Pineapple = apple as Pineapple |
08 | if let obj = apple as? Pineapple { |
想了解更多这方面内容请参见Type Casting一章.
泛型 泛型是Swift的一个加分的特点。他们看起来有一点像C++里面的模板,但是有更强的型别,也更简单(更简单使用,功能稍逊)。 02 | protocol DoubleConvertible { |
03 | @prefix func +(v: Self) -> Double |
05 | @prefix func +(v: Int) -> Double { return Double(v) } |
06 | extension Double: DoubleConvertible {} |
07 | extension Int: DoubleConvertible {} |
13 | class var dimensions: Int { get } |
14 | func getCoordinate(dimension: Int) -> T |
18 | struct Pythagoras<P1: PointTraits, P2: PointTraits where P1.T: DoubleConvertible, P2.T: DoubleConvertible> { |
19 | static func apply(a: P1, b: P2, dimensions: Int) -> Double { |
23 | let d: Double = +a.getCoordinate(dimensions-1) - +b.getCoordinate(dimensions-1) |
24 | return d * d + apply(a, b: b, dimensions: dimensions-1) |
26 | static func apply(a: P1, b: P2) -> Double { |
27 | let dimensions = P1.dimensions |
28 | assert (P2.dimensions == dimensions) |
29 | return apply(a, b: b, dimensions: dimensions) |
33 | import func Foundation. sqrt |
35 | func distance<P1: PointTraits, P2: PointTraits where P1.T: DoubleConvertible, P2.T: DoubleConvertible>(a: P1, b: P2) -> Double { |
36 | assert (P1.dimensions == P2.dimensions) |
37 | return sqrt (Pythagoras.apply(a, b: b)); |
41 | struct Point2D<Number> : PointTraits { |
42 | static var dimensions: Int { return 2 } |
43 | var x: Number, y: Number |
44 | func getCoordinate(dimension: Int) -> Number { return dimension == 0 ? x : y } |
46 | let a = Point2D(x: 1.0, y: 2.0) |
47 | let b = Point2D(x: 5, y: 5) |
48 | Pythagoras.apply(a, b: b) |
52 | extension UIColor : PointTraits { |
53 | class var dimensions: Int { return 4 } |
54 | func getCoordinate(dimension: Int) -> Double { |
55 | var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0 |
56 | getRed(&red, green: &green, blue: &blue, alpha: &alpha) |
65 | distance(UIColor.redColor(), UIColor.orangeColor()) |
以上代码是受Boost中的Design Rationale的启发.几何的C++库。Swift中的泛型功能不是那么强,但是却能使源码比C++中泛型更具阅读性。
Swift的泛型是通过类型参数化的。每个参数类型要求实现一个特定的协议或者继承自一个特定的基类。在申明参数类型后,有一个可选的"where"项目能用于给这个类型(或者是他们的内部类型,就如上面那个PointTraits协议中的别名'T')添加额外的需求。这个"where“也能要求两种类型是相等的。
苹果有更多更完整的Generics章节。
选定Swift 现在你已经准备好了去看各种各样的源码了,甚至可以自己写了 :-)
在把你自己留在一个新的大的Swift未知大陆之前,我有几个最终的建议: Apple推荐你使用Int作为所有Integer类型,即使你之前用无符号数的地方。“只有在你真的需要一个与平台原生大小想相同的无符号integer类型时再使用UInt类型.” 如果你想知道@private和al.在哪:好吧,他们还没完成呢,后续版本会加进来的。 如果你创建了一个module,你可以Cmd+单击你的module的名字来查看你的module的自动生成的Swift头。 Swift的modules其实是命名空间,因此在任何东西前加像 CF, NS, UI等的前缀。当创建第三方库是就不是那么绝对必要了。
Enjoy using Swift! |