覆盖 swift 中的属性

Overriding properties in swift

例如第一个class

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

并继承了class:

public class SomeButton: SomeBaseButton {

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

所以,逻辑是SomeClass定义自己的文本和权重。 但我收到错误消息:

对于文本:“无法用存储的属性覆盖'text'

对于权重:“无法用已存储的 属性 'weight'”覆盖

在上面你有一个 getter 和一个 setter。

当您覆盖它时,您只是在为其分配一个值。

而是像上面那样设置 setter 和 getter。

var _text:Text

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

有趣的是,这在纯 Swift classes 中工作得很好。例如,这按预期工作:

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

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

它对你不起作用的原因是因为你正在使用 Objective-C classes:因为 UIButton 是一个 Objective-C class,它的所有子 classes 也将如此。因此,规则似乎有点不同。

Xcode 6.3 实际上提供了更多信息。它显示以下两个错误:

Getter for "weight" overrides Objective-C method "weight" from superclass "FooButton" Setter for "weight" overrides Objective-C method "setWeight:" from superclass "Foobutton"

因为以下确实有效...

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

...我的猜测是这些方法根本没有正确合成。

我想知道这是否是编译器错误。或者是缺点。因为我觉得可以办案。

也许 Swift 设计者认为在覆盖 weight 的情况下,您也可以在初始化程序中将其简单地设置为不同的值。嗯

此外,如果有人想覆盖属性以获得dynamic效果,请参阅KVO

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

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

我 运行 在 Swift 3.

中尝试覆盖 NSPredicateRowEditor templateViews 属性 时遇到了这个问题

要覆盖的超类 属性:

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

        //}
    }

}