web-dev-qa-db-ja.com

swiftでプロパティをオーバーライドする

たとえば、最初のクラスがあります

public class MyBaseButton: UIButton {

    public var weight: Double = 1.0

    public var text: String? {
        get {
            return self.titleForState(.Normal)
        }
        set {
            return self.setTitle(newValue, forState: .Normal)
        }
    }
}

そして継承されたクラス:

public class SomeButton: SomeBaseButton {

    override public var text: String? = "text"
    override public var weight: Double = 2.0
}

したがって、ロジックはSomeClassが独自のテキストと重みを定義するということです。しかし、私はエラーが発生しています:

テキスト用: "保存されたプロパティ 'text'でオーバーライドできません"

重量の場合: "保存されたプロパティ「重量」でオーバーライドできません"

33
Vasyl Khmil

興味深いことに、これは純粋なSwiftクラスでうまく機能します。たとえば、これは期待どおりに機能します。

public class FooButton {
    public var weight: Double = 1.0
}

public class BarButton: FooButton {
    override public var weight: Double = 2.0
}

これが機能しない理由は、Objective-Cクラスを使用しているためです。UIButtonはObjective-Cクラスであるため、そのサブクラスもすべて使用されます。そのため、ルールは少し異なるようです。

Xcode 6.3は実際にはもう少し情報が豊富です。次の2つのエラーが表示されます。

「重量」のゲッターは、スーパークラス「FooButton」のObjective-Cメソッド「weight」をオーバーライドします「重量」のセッターは、スーパークラス「Foobutton」のObjective-Cメソッド「setWeight:」をオーバーライドします

以下が機能するので...

public class BarButton: FooButton {
    override public var weight: Double {
        get {
            return 2.0
        }
        set {
            // Do Nothing
        }
    }
}

...私の推測では、これらのメソッドは単純に正しく合成されていません。

これはコンパイラのバグなのでしょうか。または欠点。私はそれをcouldと思っているからです。

たぶんSwift=デザイナーはweightをオーバーライドする場合、イニシャライザで別の値に設定することもできると考えていました。

53
Stefan Arentz

また、プロパティをオーバーライドしてdynamic効果を持たせたい場合は、 [〜#〜] kvo [〜#〜] を参照してください。

class MyClass: NSObject {
    var date = NSDate()
}

class MyChildClass: MyClass {
    dynamic override var date: NSDate {
        get { return super.date }
        set { super.date = newValue }
    }
}
8
onmyway133

上記では、ゲッターとセッターがあります。

オーバーライドすると、値が割り当てられます。

代わりに、上記のようにセッターとゲッターをセットアップします。

var _text:Text

   override public var text: String? {
            get {
                return _text
            }
            set {
                _text = newValue
            }
        }
3
Aggressor

NSPredicateRowEditor templateViewsプロパティをSwift 3。

オーバーライドするスーパークラスプロパティ:

open var templateViews: [NSView] { get }

次のようにオーバーライドします。

class CustomRowTemplate: NSPredicateEditorRowTemplate {

    override var templateViews: [NSView] {
        get {
            let templateViews = super.templateViews

            // custom subclass work goes here

            return templateViews
        }
        //set {

        // Superclass property is `get` only, other properties might need a setter

        //}
    }

}
1
pkamb