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

假设我们有:

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

我猜没什么好看的。

现在,如果我尝试在派生类中重写getter:
public class MyDerivedClass: MyBaseClass {
    public var name: String {
        get {
            return "Derived - \(super.name)"
        }
    }
}

我收到编译错误:无法使用只读属性'name'覆盖可变属性。

如果我尝试添加二传手并覆盖它:
public class MyDerivedClass: MyBaseClass {
    public internal(set) var name: String {
        get {
            return "Derived - \(super.name)"
        }
        set {
            super.name = newValue
        }
    }
}

我收到错误消息:覆盖var的setter必须与其覆盖的声明一样易于访问。

如果我尝试以下操作:
public class MyDerivedClass: MyBaseClass {
    public internal(set) var name: String {
        get {
            return "Derived - \(super.name)"
        }
    }
}

然后,编译器崩溃了……

如何实现仅覆盖 setter/getter ?

最佳答案

这对我有用:

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

编辑

该代码在操场上对我有用,将其放在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() {

    }
}

这有点麻烦,因为我收到与您相同的警告,即internal(set)无法放置在重写的子类变量之前。这很可能是一个错误。而且我还在作弊以确保派生类的二传手什么也不做。
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() {

    }
}

在这里可以使用MyDerivedClass()._name直接读取 setter ,但是不能更改它,例如此MyDerivedClass()._name = "Fred"将引发错误,但MyDerivedClass().name = "Fred"可以。

09-10 13:25
查看更多