Swift中压倒一切的getter

Swift中压倒一切的getter,swift,inheritance,overriding,getter-setter,Swift,Inheritance,Overriding,Getter Setter,我需要重写属性的getter 假设我们有: 我想没什么特别的 现在,如果我尝试重写派生类中的getter: 我得到编译错误:无法用只读属性“name”覆盖可变属性 如果我尝试添加setter并覆盖它: 我得到一个错误:重写var的Setter必须和它重写的声明一样可访问 如果我尝试以下方法: 然后,编译器崩溃 如何实现仅覆盖getter?这对我很有用: public class MyBaseClass { private var _name: String = "Hi"

我需要重写属性的getter

假设我们有:

我想没什么特别的

现在,如果我尝试重写派生类中的getter:

我得到编译错误:无法用只读属性“name”覆盖可变属性

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

我得到一个错误:重写var的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)
不能放在被重写的子类变量之前。这很可能是一个错误。而且我还作弊以确保派生类的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() {

    }
}
这里可以使用
MyDerivedClass()直接读取setter。\u name
但不能更改,例如,此
MyDerivedClass()。\u name=“Fred”
将引发错误,但
MyDerivedClass()。name=“Fred”
将正常。

问题1 MyBaseClass未编译,因为:

  • 它有一个存储属性(\u name)
  • 此存储属性是非可选的,因此不能为nil
  • 没有初始值设定项来填充它
  • 因此,首先我们需要向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
        }
    }
    
    问题2 现在,我们可以声明覆盖计算属性的
    MyDerivedClass

  • 我们需要使用神奇的关键字覆盖
  • 我们需要同时提供setter和getter
  • 代码如下:

    public class MyDerivedClass: MyBaseClass {
        public override var name: String {
            get { return "Derived - \(super.name)" }
            set { super.name = newValue }
        }
    }
    
    试验 从我的操场:

    let somethingWithAName = MyDerivedClass(name: "default name")
    println(somethingWithAName.name) // > "Derived - default name"
    somethingWithAName.name = "another name"
    println(somethingWithAName.name) // > "Derived - another name"
    

    这会公开setter吗?将internal(set)放在计算变量之前表示可以公开检索,但只能在内部设置。我认为BPCorp希望在重写属性的子类中复制这些条件,但似乎不可能,因为您不能重复使用internal(set)。虫子?意外的使用模式?仅澄清一下,您需要一个只能在内部设置的计算变量(名称),但其值在这些维度之外基本上是只读的:“内部访问使实体能够在其定义模块的任何源文件中使用,但不能在该模块之外的任何源文件中使用。定义应用程序或框架的内部结构时,通常使用内部访问。“虽然_name是私有的,设置和获取仅限于源文件。我已经在twitter上得到一位Swift编译器工程师的确认,这种行为看起来像一个bug。确切地说,我目前正在尝试创建一个框架,我得到的情况是基类的设置器必须是内部的(因此,只有这个框架的其他类可以使用它)。我还尝试将
    name
    直接作为存储属性,但无法覆盖getter(如果我记得正确的话)。
    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() {
    
        }
    }
    
    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
        }
    }
    
    public class MyDerivedClass: MyBaseClass {
        public override var name: String {
            get { return "Derived - \(super.name)" }
            set { super.name = newValue }
        }
    }
    
    let somethingWithAName = MyDerivedClass(name: "default name")
    println(somethingWithAName.name) // > "Derived - default name"
    somethingWithAName.name = "another name"
    println(somethingWithAName.name) // > "Derived - another name"