LoginSignup
3
0

More than 5 years have passed since last update.

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

Posted at

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

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0