在Swift中压倒getter

BPC*_*orp 27 inheritance overriding getter-setter swift

我有一种情况需要覆盖属性的getter.

假设我们有:

public class MyBaseClass {
    private var _name: String
    public internal(set) var name: String {
        get {
            return self._name
        }
        set {
            self._name = newValue
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我猜,没什么特别的.

现在,如果我尝试覆盖派生类中的getter:

public class MyDerivedClass: MyBaseClass {
    public var name: String {
        get {
            return "Derived - \(super.name)"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到编译错误:无法使用只读属性"name"覆盖mutable属性.

如果我尝试添加setter并覆盖它:

public class MyDerivedClass: MyBaseClass {
    public internal(set) var name: String {
        get {
            return "Derived - \(super.name)"
        }
        set {
            super.name = newValue
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到错误:覆盖var的setter必须与它覆盖的声明一样可访问.

如果我尝试以下方法:

public class MyDerivedClass: MyBaseClass {
    public internal(set) var name: String {
        get {
            return "Derived - \(super.name)"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,编译器崩溃了......

我怎样才能实现只覆盖吸气剂?

ske*_*ech 25

这对我有用:

    public class MyBaseClass {
        private var _name: String = "Hi"
        public internal(set) var name: String {
            get {
                return self._name
            }
            set {
                self._name = newValue
            }
        }
    }

    public class MyDerivedClass:MyBaseClass {
        override public var name: String {
            get {
                return "Derived - \(super.name)"
            }
            set {
                super._name = newValue
            }
        }
    }

    MyDerivedClass().name
Run Code Online (Sandbox Code Playgroud)

编辑

这段代码适用于我在游乐场,将它放在Sources - > SupportCode.swift文件中

    public class MyBaseClass {
    private var _name: String = "Hi"
    public internal(set) var name: String {
        get {
            return self._name
        }
        set {
            self._name = newValue
        }
    }
    public init() {

    }

    }

    public class MyDerivedClass:MyBaseClass {
        override public var name: String {
            get {
                return "Derived - \(super.name)"
            }
            set {
               // do nothing
            }
        }
       public override init() {

        }
    }
Run Code Online (Sandbox Code Playgroud)

这有点像一个小窍门,因为我得到的警告与你internal(set)在被覆盖的子类变量之前无法放置的警告相同.这可能是一个错误.而且我也在作弊,以确保派生类的setter什么都不做.

的一个更常见的用途internal(set)private(set)就是有这样的代码,这类似于本文档中:

public class MyBaseClass {
    public private(set) var _name: String = "Hi"
    public var name: String {
        get {
            return self._name
        }
        set {
            self._name = newValue
        }
    }
    public init() {

    }

}

public class MyDerivedClass:MyBaseClass {
    override public var name: String {
        get {
            return "Derived - \(super.name)"
        }
        set {
           super._name = newValue
        }
    }
   public override init() {

    }
}
Run Code Online (Sandbox Code Playgroud)

这里的setter可以直接读取,MyDerivedClass()._name但不能改变,例如,这MyDerivedClass()._name = "Fred"会引起错误但是没问题MyDerivedClass().name = "Fred".


Luc*_*tti 6

问题1

MyBaseClass 无法编译,因为:

  1. 它有一个存储属性(_name)
  2. 这个存储的属性是非可选的,所以它不能为零
  3. 没有初始化程序来填充它

首先,我们需要为MyBaseClass添加一个合适的初始化程序

public class MyBaseClass {
    private var _name: String
    public internal(set) var name: String {
        get { return self._name }
        set { self._name = newValue }
    }
    init(name : String){
        _name = name
    }
}
Run Code Online (Sandbox Code Playgroud)

问题2

现在我们可以声明MyDerivedClass覆盖计算属性:

  1. 我们需要使用magic关键字覆盖
  2. 我们需要同时提供setter和getter

这是代码:

public class MyDerivedClass: MyBaseClass {
    public override var name: String {
        get { return "Derived - \(super.name)" }
        set { super.name = newValue }
    }
}
Run Code Online (Sandbox Code Playgroud)

测试

从我的操场上:

let somethingWithAName = MyDerivedClass(name: "default name")
println(somethingWithAName.name) // > "Derived - default name"
somethingWithAName.name = "another name"
println(somethingWithAName.name) // > "Derived - another name"
Run Code Online (Sandbox Code Playgroud)