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

时间:2016-01-14 09:46:07

标签: swift swift2

有没有办法在不引入新属性的情况下更改子类中的Swift属性可见性?

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

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

public class MyClass: MyBaseClass
{
    public override var abc: Int = 0 // this cannot be compiled
}

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

  

无法覆盖存储的属性'abc'

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

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

        set
        {
            abc = newValue
        }

    }
}

3 个答案:

答案 0 :(得分:4)

Swift有两种类型的属性:存储属性和计算属性。您可以覆盖它们,但覆盖版本不能是存储属性,您必须使用计算属性覆盖。

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

请参阅Inheritance - OverridingOverriding Properties

部分
  

您可以覆盖继承的实例或类型属性,以便为该属性提供自己的自定义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 {
        }
    }
}

答案 1 :(得分:3)

这看起来更好

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

有些人声称这是编译器的一个错误,它没有正确地合成覆盖的属性。

答案 2 :(得分:-2)

尝试以下方法:

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


public class MyClass: MyBaseClass {
    override init() {
        super.init()
        self.abc = 0
    }
}