如何更改子类中的Swift属性可见性

如何更改子类中的Swift属性可见性,swift,swift2,Swift,Swift2,有没有一种方法可以在不引入新属性的情况下改变子类中Swift属性的可见性 我想做的是(将属性初始化为默认值不是强制性要求): 上面的代码显示编译器错误: 无法使用存储属性“abc”重写 目前我唯一能解决这个问题的方法是引入另一个属性,但这不是我喜欢做的: public class MyClass: MyBaseClass { public var abcd: Int { get { return abc }

有没有一种方法可以在不引入新属性的情况下改变子类中Swift属性的可见性

我想做的是(将属性初始化为默认值不是强制性要求):

上面的代码显示编译器错误:

无法使用存储属性“abc”重写

目前我唯一能解决这个问题的方法是引入另一个属性,但这不是我喜欢做的:

public class MyClass: MyBaseClass
{
    public var abcd: Int
    {
        get
        {
            return abc
        }

        set
        {
            abc = newValue
        }

    }
}
请尝试以下操作:

    public class MyClass: MyBaseClass {
    private var abc: Int = 0
}


public class MyClass: MyBaseClass {
    override init() {
        super.init()
        self.abc = 0
    }
}
这个看起来好多了

public class MyClass: MyBaseClass {
    override public var abc: Int {
        get {
            return super.abc
        }
        set {
            super.abc = newValue
        }
    }
}

有些人声称这是编译器的一个bug,它不能正确地合成被重写的属性

Swift有两种类型的属性:存储属性和计算属性。您可以同时重写这两个属性,但被重写的版本不能是存储属性,必须使用计算属性进行重写

请注意,存储的属性只是内存块,而计算的属性是两个方法的集合—getter和setter。不能用另一块内存覆盖一块内存,但可以覆盖一个方法

请参阅,章节
覆盖属性

您可以重写继承的实例或类型属性,为该属性提供您自己的自定义getter和setter,或者添加属性观察器,以便在基础属性值更改时能够观察重写属性

您可以提供一个自定义的getter(和setter,如果合适的话)来重写任何继承的属性,而不管继承的属性是在源位置实现为存储属性还是计算属性。子类不知道继承属性的存储或计算性质,它只知道继承属性具有特定的名称和类型。您必须始终声明要重写的属性的名称和类型,以使编译器能够检查您的重写是否与具有相同名称和类型的超类属性匹配

通过在子类属性重写中同时提供getter和setter,可以将继承的只读属性表示为读写属性。但是,不能将继承的读写属性显示为只读属性

还有一个提示:在

如果在属性重写中提供setter,则还必须为该重写提供getter。如果不想在重写getter中修改继承属性的值,只需通过从getter返回super.someProperty来传递继承值,其中someProperty是要重写的属性的名称

这正好告诉我们该怎么做:

public class MyClass: MyBaseClass {
    public override var abc: Int {
        get {
           return super.abc
        }
        set {
           super.abc = newValue
        }
    }
}
请注意,以下操作也可以。我们只需确保有一个计算属性:

public class MyClass: MyBaseClass {
    public override var abc: Int {
        didSet {
        }
    }
}

与我的解决方案完全相同。考虑到原始代码的错误消息是
error:cannot override with a storage property'abc'
,在我看来,这更像是一个预期行为,而不是一个bug。看起来不错,但我在游乐场获得了对
let b=MyClass()b.abc=1
@DalijaPrasnikar的EXC_BAD_访问权限。我已经修复了这个问题。重写变量的问题在于,您不能这样做。从未。您实际上覆盖的是方法,即属性的getter和setter。谢谢,它现在可以工作了。我仍然习惯于快速做事的方式。你能把这句话也写进你的答案吗。它确实解释了后台发生的事情。@Sulthan您能解释一下为什么文档明确说明您可以重写属性吗?我是否误解了这种情况?我正在尝试更改属性的可见性,而不是初始化。
public class MyClass: MyBaseClass {
    public override var abc: Int {
        didSet {
        }
    }
}