發現swift和java有一個徹底不同的地方
在swift中, 子類必須先初始化子類的全部屬性, 而後才能調用父類的構造器. 而在java中.super調用必須出如今構造函數的第一行.
java代碼java
public class Dog { String name; Dog(String name){ this.name = name; } } class NoisyDog extends Dog { int age; NoisyDog(String name) { // 交換如下兩行的順序會報錯: Constructor call must be the first statement in a constructor super(name); this.age = 5; } }
對應的swift代碼:swift
class Dog { var name: String; init(name: String){ self.name = name; } } class NoisyDog: Dog { var age: Int override init(name: String) { //交換如下兩行的順序會報錯error: property 'self.age' not initialized at super.init call self.age = 5; super.init(name: name); } }
書中關於failable initializer描述有錯誤
如下代碼在swift2.1及以前會編譯錯誤, 在swift2.2中修正了這個bug
swift2.2: 子類failable designated 構造器在返回nil前沒必要初始化子類的屬性也沒必要調用父類的designated initializer, 也就是說, 在子類的failable initilizer中容許提早返回nilide
//: Playground - noun: a place where people can play import Foundation class Dog{ var name: String init(name: String){ self.name = name } } class NoisyDog : Dog { var age: Int override init(name: String){ self.age = 5 super.init(name: name) } init?(name: String, age: Int){ // as of swift2.2: 子類failable designated 構造器在返回nil前沒必要初始化子類的屬性 // 也沒必要調用父類的designated initializer if age < 0 { return nil } self.age = age; super.init(name: name) } }
見:
http://stackoverflow.com/questions/26495586/best-practice-to-implement-a-failable-initializer-in-swift/26497229#26497229函數