覆盖 Swift 中的 getter
Overriding getter in Swift
我有一种情况需要覆盖 属性 的 getter。
假设我们有:
public class MyBaseClass {
private var _name: String
public internal(set) var name: String {
get {
return self._name
}
set {
self._name = newValue
}
}
}
我想没什么特别的。
现在,如果我尝试覆盖派生的 class 中的 getter:
public class MyDerivedClass: MyBaseClass {
public var name: String {
get {
return "Derived - \(super.name)"
}
}
}
我收到编译错误:无法用只读覆盖可变 属性 属性 'name'.
如果我尝试添加 setter 并覆盖它:
public class MyDerivedClass: MyBaseClass {
public internal(set) var name: String {
get {
return "Derived - \(super.name)"
}
set {
super.name = newValue
}
}
}
我收到错误消息:Setter 覆盖 var 必须与其覆盖的声明一样可访问。
如果我尝试以下操作:
public class MyDerivedClass: MyBaseClass {
public internal(set) var name: String {
get {
return "Derived - \(super.name)"
}
}
}
然后,编译器崩溃了...
我怎样才能实现只覆盖 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
编辑
这段代码在 playground 中对我有用,将它放在 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)
不能放在被覆盖的 subclass 变量之前。这很可能是一个错误。而且我也在作弊以确保派生 class 的 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() {
}
}
这里的setter可以直接用MyDerivedClass()._name
读取,但是不能修改,例如MyDerivedClass()._name = "Fred"
会引发错误,但 MyDerivedClass().name = "Fred"
没问题。
问题 1
MyBaseClass 不编译 因为:
- 它已存储 属性 (_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
来覆盖计算的 属性:
- 我们需要使用魔法关键字override
- 我们需要同时提供 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"
我有一种情况需要覆盖 属性 的 getter。
假设我们有:
public class MyBaseClass {
private var _name: String
public internal(set) var name: String {
get {
return self._name
}
set {
self._name = newValue
}
}
}
我想没什么特别的。
现在,如果我尝试覆盖派生的 class 中的 getter:
public class MyDerivedClass: MyBaseClass {
public var name: String {
get {
return "Derived - \(super.name)"
}
}
}
我收到编译错误:无法用只读覆盖可变 属性 属性 'name'.
如果我尝试添加 setter 并覆盖它:
public class MyDerivedClass: MyBaseClass {
public internal(set) var name: String {
get {
return "Derived - \(super.name)"
}
set {
super.name = newValue
}
}
}
我收到错误消息:Setter 覆盖 var 必须与其覆盖的声明一样可访问。
如果我尝试以下操作:
public class MyDerivedClass: MyBaseClass {
public internal(set) var name: String {
get {
return "Derived - \(super.name)"
}
}
}
然后,编译器崩溃了...
我怎样才能实现只覆盖 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
编辑
这段代码在 playground 中对我有用,将它放在 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)
不能放在被覆盖的 subclass 变量之前。这很可能是一个错误。而且我也在作弊以确保派生 class 的 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() {
}
}
这里的setter可以直接用MyDerivedClass()._name
读取,但是不能修改,例如MyDerivedClass()._name = "Fred"
会引发错误,但 MyDerivedClass().name = "Fred"
没问题。
问题 1
MyBaseClass 不编译 因为:
- 它已存储 属性 (_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
来覆盖计算的 属性:
- 我们需要使用魔法关键字override
- 我们需要同时提供 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"