はてな教科書の「プログラミング言語 Swift」を読んでます 5
https://github.com/hatena/Hatena-Textbook/blob/master/swift-programming-language.md
イニシャライザが難しかったのですが、のんびり読んでいきます。
Inheritance
class名の右に:
をつけてスーパークラスを指定することでそのクラスを継承することができます。
スーパークラスの実装を明示的に利用する場合は、super
キーワードを用います。
1> class Man { 2. func greeting() -> String { 3. return "Hello" 4. } 5. } 6> class Student : Man { 7. override func greeting() -> String { 8. return "\(super.greeting()), Teacher" 9. } 10. } 11> let taro: Man = Student() taro: Student = { __lldb_expr_1.Man = {} } 12> taro.greeting() $R0: String = "Hello, Teacher"
final
キーワードをclass
やfunc
につけることで継承を制限することができます。
Initializers and deinitializers
Initializers
- class, enum, structではイニシャライザが定義できる
- イニシャライザでは、Optional型ではないstoredプロパティ(let, varをつけるいわゆる普通のインスタンス変数ないしクラス変数)で、初期値が設定されていないものをすべて初期化する必要がある
- イニシャライザは複数定義可能で、メソッドとは異なり第一引数からラベルを明記する
- 型が同じでもラベルによってイニシャライザが区別される
- 下記の条件で、class はデフォルトで空のイニシャライザを持つ
- イニシャライザが一つも定義されておらず
- かつイニシャライザで初期化するべき stored プロパティが存在しない
- 下記の条件で、 structは全ての初期化すべき stored プロパティを定義順に指定するデフォルトのイニシャライザを持つ
- イニシャライザが一つも定義されていない場合
値型のイニシャライザ
- 値型は
enum
,struct
- enum型のイニシャライザについては http://qiita.com/_mpon/items/4491d19fa50b2039af35 など
http://qiita.com/cotrpepe/items/3052d91468f1b852582a http://qiita.com/qoAop/items/a28e3649feaf38af1134
// 参考: http://qiita.com/_mpon/items/4491d19fa50b2039af35 18> enum Size { 19. case Small, Medium, Large 20. 21. // 引数なしコンストラクタ 22. init() { 23. self = .Small // デフォルト値の設定など 24. } 25. } 26> Size() $R3: Size = Small
// 値型の場合は self.init で自身のイニシャライザを呼び出すことができるのenumのそれがわからない..。 27> enum Size { 28. case Small, Medium, Large 29. 30. // 引数なしコンストラクタ 31. init() { 32. self = .Small 33. } 34. init(type: Int) { 35. if type % 3 == 0 { 36. self = .Medium 37. } else { 38. self = self.init 39. } 40. } 41. } repl.swift:38:25: error: cannot assign value of type '_ -> _' to type 'Size' self = self.init ~~~~~^~~~ // Structの場合は https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html より 1> struct Size { 2. var width = 0.0, height = 0.0 3. } 4. struct Point { 5. var x = 0.0, y = 0.0 6. } 7> 8> struct Rect { 9. var origin = Point() 10. var size = Size() 11. init() {} 12. init(origin: Point, size: Size) { 13. self.origin = origin 14. self.size = size 15. } 16. init(center: Point, size: Size) { 17. let originX = center.x - (size.width / 2) 18. let originY = center.y - (size.height / 2) 19. self.init(origin: Point(x: originX, y: originY), size: size) 20. } 21. }
参照型のイニシャライザ
- designated イニシャライザはclass中の初期値が与えられていないletやvarのstoredプロパティの値をすべて定義する
- ほかのイニシャライザには
convenience
修飾子をつける- convenienceイニシャライザはdesignated イニシャライザを呼び出さなければいけない
- クラスを継承している場合は、必ずsuperclassのイニシャライザを呼び出さなければいけない
42> class Initial { 43. var name: String 44. init() { 45. name = "Sample" 46. } 47. 48. convenience init(initName: String) { 49. self.init() 50. self.name = initName 51. } 52. func display() { 53. print(name.substringToIndex(name.startIndex.advancedBy(1))) 54. } 55. } 56> Initial().display() S 57> Initial(initName: "Example").display() E
SubクラスがSuperクラスのdesignated イニシャライザを定義していない場合、スーパークラスの designated イニシャライザが利用できます。
27> class Super { 28. init() { 29. print("Super") 30. } 31. } 32> class Sub : Super {} 33> Sub() Super $R1: Sub = { __lldb_expr_11.Super = {} }
required 修飾子で実装を強制することもできます。
34> class Super { 35. init() { 36. print("Super") 37. } 38. required convenience init(printString: String) { 39. self.init() 40. print(printString) 41. } 42. } 43> class Sub : Super {} 44> Sub() Super $R2: Sub = { __lldb_expr_19.Super = {} } 45> Sub(printString: "Test") Super Test $R3: Sub = { __lldb_expr_19.Super = {} }
Failable Initializers
init?
と?
をつけたイニシャライザは与えられた引数によっては初期化を失敗させてnilを返すようにできる- そのイニシャライザの返り値をしては、Optionalとなる
Deinitializers
クラスのインスタンスが破棄されるときに実行したい処理はデイニシャライザ(deinit {...}
)にて定義できる。