ios Swift 覆盖实例变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26188903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:00:07  来源:igfitidea点击:

Swift override instance variables

iosclassvariablesinheritanceswift

提问by D?nu? Mihai Florian

I know this answer has already been posted in some other form here, but I'd like to understand more about overriding instance variables in swift.

我知道这个答案已经以其他形式发布在这里,但我想了解更多关于在 swift 中覆盖实例变量的信息。

Let's say I have this code

假设我有这个代码

class BaseView:UIView{
 let someVariable:Int = 1
 // do some work with someVariable
}

class ExtendedView:BaseView{
 let someVariable:Int = 2
}

Ok. From what I read, the constant requires an override prefix. Other answers said that I should declare the setter and getter? Why? I really don't care about those two. I just need the value replaced. I can't really use the initoverride because I'm inheriting from UIView and this might be quite dangerous (i think).

好的。从我读到的内容来看,常量需要一个覆盖前缀。其他答案说我应该声明setter和getter?为什么?我真的不在乎那两个。我只需要替换值。我不能真正使用init覆盖,因为我是从 UIView 继承的,这可能非常危险(我认为)。

Any suggestions are welcomed.

欢迎任何建议。

回答by Grimxn

As you say, you cannot simply redefine a constant in a subclass (it is a constant, after all). The error you get is "Cannot override with a stored property". It does appear to be possible to override a var, however, when I change the let someVariableto var someVariableI get "ambiguous use of 'someVariable'" when I access it in the subclass (note - same thing happens whether I use overrideor not).

正如您所说,您不能简单地在子类中重新定义一个常量(毕竟它是一个常量)。您得到的错误是“无法用存储的属性覆盖”。似乎确实可以覆盖 a var,但是,当我将 更改为 时,当我在子类中访问它时let someVariablevar someVariable我得到“'someVariable' 的歧义使用”(注意 - 无论我是否使用,都会发生同样的事情override)。

The simplest solution is to use a getter. This is really a function, so you can happily override it, the backing variable will be managed for you, and if you don't supply a setter ... it will be constant for each class:

最简单的解决方案是使用吸气剂。这真的是一个函数,所以你可以愉快地覆盖它,后备变量将为你管理,如果你不提供一个 setter ......它对于每个类都是常量:

class BaseView: UIView {
    var someVariable: Int { get { return 1 } }
    // do some work with someVariable
}

class ExtendedView: BaseView {
    override var someVariable: Int { get { return 2 } }
}

let a = BaseView()
a.someVariable // 1
let b = ExtendedView()
b.someVariable // 2

As commentator @user3633673 points out, if you onlyhave a getter (and not a setter), you can drop the get, but I left it in for clarity of the principle. Here's the same without it...

正如评论员@user3633673 指出的那样,如果您只有一个 getter(而不是一个 setter),您可以删除get,但为了清晰起见,我保留了它。没有它也一样......

class BaseView: UIView {
    var someVariable: Int { return 1 }
    // do some work with someVariable
}

class ExtendedView: BaseView {
    override var someVariable: Int { return 2 }
}

let a = BaseView()
a.someVariable // 1
let b = ExtendedView()
b.someVariable // 2

... and, of course, in Swift 5, you can drop the return:

...当然,在 Swift 5 中,您可以删除return

class BaseView: UIView {
    var someVariable: Int { 1 }
}

class ExtendedView: BaseView {
    override var someVariable: Int { 2 }
}