Posted at

SwiftTourをさっと読む ~ Objects and Classes ~

More than 1 year has passed since last update.


SwiftTourをさっと読む ~ Objects and Classes ~

さっと見ていきます。


クラス


宣言


クラスの宣言

class Shape {

var numberOfSides = 0
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}

classに続けてクラス名を書くことでクラス宣言ができる。

クラスのプロパティ定義は変数や定数の宣言と同様。

ファンクションも同様。


インスタンス化


クラスのインスタンス化

var shape = Shape()

shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription() // A shape with 7 sides.

インスタンス化はクラス名の後に()を続けることでできる。

プロパティへのアクセスは.で行える。


イニシャライザ


イニシャライザメソッド

class NamedShape {

var numberOfSides: Int = 0
var name: String

init(name: String) {
self.name = name
}

func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}


init()を利用することでイニシャライザ処理を定義できる。

init内ではクラスプロパティにアクセスする際にself.nameを利用しているが、

これは引数のnameと明確に区別するため。


継承とオーバーライド


継承とオーバーライド

class Square: NamedShape {

var sideLength: Double

init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 4
}

func area() -> Double {
return sideLength * sideLength
}

override func simpleDescription() -> String {
return "A square with sides of length \(sideLength)."
}
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription() // A square with sides of length 5.2.


class 子クラス: 親クラス

他のクラスを継承する場合はクラス名の後に:を挟んで定義する。

子クラスから親クラスのメソッドを利用する場合はsuper.メソッド名で利用することができる。

親クラスのメソッドを上書きをする場合は、

overrideをメソッド名の前に付ける必要があり、overrideなしでオーバーライドを試みるとエラーになる。


getter,setter


getter,setter

class EquilateralTriangle: NamedShape {

var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
print(triangle.perimeter) // 9.3
triangle.perimeter = 9.9
print(triangle.sideLength) // 3.3

クラスのプロパティにはgettersetterがあり、これを設定することもできる。

getは任意の値を返すことができる。

setは新しい値に暗黙的にnewValueという名前が付与される。


willSet,didSet


willSet,didSet

class TriangleAndSquare {

var triangle: EquilateralTriangle {
willSet {
square.sideLength = newValue.sideLength
}
}
var square: Square {
willSet {
triangle.sideLength = newValue.sideLength
}
}
init(size: Double, name: String) {
square = Square(sideLength: size, name: name)
triangle = EquilateralTriangle(sideLength: size, name: name)
}
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
print(triangleAndSquare.square.sideLength) // 10.0
print(triangleAndSquare.triangle.sideLength) // 10.0
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
print(triangleAndSquare.triangle.sideLength) // 50.0

新しい値(newValue)を設定する前後に実行するコードを書く場合は、

willSet及びdidSetが利用できる。

このコードはイニシャライザ以外で値に変更があった場合に実行される。


オプショナルの操作


オプショナルの操作

let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")

let sideLength = optionalSquare?.sideLength

オプショナルの値を扱う際には、操作の前に?を書くことができる。

?より前の値がnilの場合、?以降が全て無視され、nilとなる。

?より前の値がnilでない場合、?以降の全ての値がアンラップされた値として作用する。

いずれの場合も式全体はオプショナルの値となる。


おわり

willSetdidSetは知らんかったです。

特定の値が変更された際に他の値の正しさを保証するイメージなのかな?

おしまい。


過去記事

Simple Values

Control Flow

Functions and Closures