在Swift中创建子类时如何避免重复属性定义?



在下面的代码中,我认为我被迫键入冗余,即类Beverage及其子类Beer的init()函数都指定属性nameform。但这似乎违反直觉,因为我认为使用子类的好处是继承类属性,所以不是为每个子类重新输入超类属性弄巧成吗?(没有双关语)。此外,无限地要求super.init(form: form, name: name, etc: etc)似乎有点荒谬。我错过什么了吗?


class Beverage {
var name: String
var form: String

init(name: String = "unknown",
form: String = "liquid") {
self.name = name
self.form = form
}
}
class Beer: Beverage {
var alcohol: Double?

init(name: String = "unknown",
form: String = "liquid",
alcohol: Double?) {
self.alcohol = alcohol
super.init(name: name, form: form)
}
}

let myBev = Beer(name: "Heineken", alcohol: 0.05)
if let alcohol = myBev.alcohol {
print("I'm drinking a glass of (myBev.name), which is a (myBev.form) and has (alcohol)% alcohol.")
} else {
print("I'm drinking a glass of (myBev.name), which is a (myBev.form).")
}
// prints "I'm drinking a glass of Heineken, which is a liquid and has 0.05% alcohol."

我试图删除我认为是多余的代码,但它不再工作;我被冗余困扰了吗?

根据规则,你必须调用super来初始化属性,而不需要在基类中声明默认值。

但是您可以通过省略具有固定值的参数来消除一点冗余,例如在Beer类中,很明显形式是liquid

class Beer: Beverage {
var alcohol: Double

init(name: String, alcohol: Double) {
self.alcohol = alcohol
super.init(name: name, form: "liquid")
}
}

另一种方法是在基类

中为liquidbeverages添加一个方便的初始化器(调用指定初始化器)。
class Beverage {
var name : String
var form : String

init(name: String, form: String) {
self.name = name
self.form = form
}

convenience init(name: String) {
self.init(name: name, form: "liquid")
}
}

Beer中的代码可以简化为

class Beer: Beverage {
var alcohol: Double

convenience init(name: String, alcohol: Double) {
self.init(name: name)
self.alcohol = alcohol
}
}

注意convenience初始化器调用self而不是super

我将alcohol声明为非可选的。

最新更新