クラスの定義は、class に続けてクラス名を記述します。クラスでのプロパティの宣言は、定数や変数の宣言と同じように記述し、メソッドと関数の宣言でも同様です。

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
EXPERIMENT
let の定数プロパティと、引数を取るメソッドを追加してみよう。

クラス名の後に丸括弧を置いてクラスのインスタンスを生成します。インスタンスのプロパティとメソッドにアクセスするにはドットシンタックスを用います。

var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

Shape クラスのこのバージョンには、インスタンス生成時にセットアップするイニシャライザがありません。これには init を利用します。

class NamedShape {
    var numberOfSides: Int = 0
    var name: String

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

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

イニシャライザの name 引数と name プロパティを区別するために、self が使われていることに注目してください。クラスのインスタンスを生成する際、関数呼び出しと同じようにイニシャライザに引数を渡します。すべてのプロパティに値が代入される必要があります。numberOfSides のように宣言時か、name のようにイニシャライザで代入します。

オブジェクトが解放される前にクリーンアップの処理が必要な場合は、デイニシャライザを生成する deinit を用います。

サブクラスは、クラス名の後にコロンで区切ってスーパークラス名を記述します。標準のルートクラスを記述する必要はなく、必要に応じてスーパークラスを含めることができます。

スーパークラスの実装をオーバーライドするサブクラスのメソッドには override を付けます。override の無いメソッドをオーバーライドすると、コンパイラによってエラーとして検出されます。コンパイラは、override が付けられたメソッドが、実際にはスーパークラスのメソッドをオーバーライドしていないことも検出します。

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()
EXPERIMENT
イニシャライザの引数として radius と name を取る Circle クラスを、NamedShape のサブクラスとして定義し、area() と simpleDescription() メソッドを実装してみよう。

プロパティには、get アクセサと set アクセサを持たせることができます。

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
        }
    }

    override func simpleDescription() -> String {
        return "An equilateral triangle with sides of length \(sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
print(triangle.perimeter)
triangle.perimeter = 9.9
print(triangle.sideLength)

perimeter の set アクセサには、新たに設定される値を持つ newValue があります。set の後に丸括弧で囲んで別の名前を付けることもできます。

EquilateralTriangle クラスのイニシャライザには 3 つのステップがあることに注目してください。

  1. サブクラスで宣言しているプロパティの値を設定
  2. スーパークラスのイニシャライザを呼び出す
  3. スーパークラスで定義されているプロパティの値を変更する。ここに、メソッドや get / set アクセサを追加することができます。

プロパティを算出する必要は無いものの、新しい値が設定される前後にコードを実行させたい場合には、willSet と didSet を使用します。このコードは、イニシャライザの外で値が変更されるときに実行されます。例として、次のクラス TriangleAndSquare は、三角形 (triangle) の辺の長さ (sideLength) が、正方形 (square) の辺の長さと常に同じになります。

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)
print(triangleAndSquare.triangle.sideLength)
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
print(triangleAndSquare.triangle.sideLength)

オプショナル値を扱うとき、メソッドやプロパティ、サブスクリプティングの前に ? を置くことができます。値が nil の場合、? の後は無視され、式全体の値が nil となります。nil でない場合には、オプショナル値はアンラップされ、? の後の処理はアンラップされた値を対象にします。両方のケースで、式全体の値はオプショナル値となります。

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

Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.