web-dev-qa-db-ja.com

プロパティオブザーバーをオーバーライドする

関数noiseをオーバーライドすると、関数は新しい関数に置き換えられます。しかし、オブザーバーでプロパティをオーバーライドすると、古い値と新しい値の両方が実行されます。

遊び場で:

class Vehicle {
    func noise(sound: String) {
        println("Vehicle sound sounds like \(sound)")
    }
}

class Train: Vehicle {
    override func noise(sound: String) {
        println("A train does: \(sound)")
    }
}

出力:

var oldTrain = Train()
bulletTrain.noise("tjoek tjoek") // Prints: "A train does: tjoek tjoek"

しかし、オブザーバーを持つプロパティで同じことをすると:

遊び場で:

class Foo {
    var something: Int! {
        didSet {
            println("vroom")
        }
    }
}

class Bar: Foo {
    override var something: Int! {
        didSet {
            println("toot toot")
        }
    }
}

出力:

var foobar = Bar()
foobar.something = 3 // Prints: "vroom" & "toot toot"

では、プロパティをオブザーバーでオーバーライドする方法と、古い値が実行されないようにする方法を教えてください。

20
Eendje

プロパティのsetgetの部分をオーバーライドして、printlnをそこに移動できます。このようにSwiftは元のコードを呼び出しません-superを呼び出さない限り)。

class Foo {
    private var _something: Int!

    var something: Int! {
        get {
            return _something
        }
        set {
            _something = newValue
            println("vroom")
        }
    }
}

class Bar: Foo {
    override var something: Int! {
        get {
            return _something
        }
        set {
            _something = newValue
            println("toot toot")
        }
    }
}

しかし、それはきれいではありません。

ここに、より優れた、よりシンプルなソリューションがあります。

class Foo {
    var something: Int! {
        didSet {
            somethingWasSet()
        }
    }

    func somethingWasSet() {
        println("vroom")
    }
}

class Bar: Foo {
    override func somethingWasSet() {
        println("toot toot")
    }
}

didSetを「オーバーライド」する方法がないため、残っているのは、その目的のために特別に作成された2次関数をオーバーライドしていることです。

32
Jean Le Moignan

Swiftのドキュメント から

スーパークラスの初期化子が呼び出された後、サブクラスの初期化子でプロパティが設定されると、スーパークラスのプロパティのwillSetおよびdidSetオブザーバーが呼び出されます。スーパークラス初期化子が呼び出される前に、クラスが独自のプロパティを設定している間は呼び出されません。

1

サブクラスのオブザーバーは、スーパークラスで定義されたオブザーバーにのみ追加されます。

公式ドキュメントから: 上書き

上書きプロパティ

継承されたインスタンスまたはタイププロパティをオーバーライドして、そのプロパティに独自のカスタムゲッターおよびセッターを提供したり、またはプロパティオブザーバーを追加してオーバーライドするプロパティを有効にしたりできます。基本となるプロパティ値がいつ変化するかを観察します。

0
Lubbo