Swift初始化期间常量属性的概念

时间:2017-03-14 20:53:23

标签: swift properties initialization

“ 对于类实例,只能通过引入它的类在初始化期间修改常量属性。它不能被子类修改。“ 摘录自:Apple Inc.“The Swift Programming Language(Swift 3.1)。”iBooks。

我很难理解这一点,因为我也可以通过子类修改属性。 以下是代码。

class ConstantTest {
    let constant: String
    init(constant: String) {
        self.constant = constant
    }
    func printConstant() {
        print(constant)
    }
}

let constanttest = ConstantTest(constant: "Hello")
constanttest.printConstant()

class SubConstClass: ConstantTest { }

var subTest = SubConstClass(constant: "hey")
subTest.printConstant()

3 个答案:

答案 0 :(得分:2)

混淆的关键是子类初始化常量属性意味着什么。这意味着子类不能引入分配值的初始化程序。让我们考虑一个简单的案例:

class Person {
    let name: String
    init() {
        name = "Alice"
    }
}

这可以通过在其声明中指定name来更简单地编写,但我希望这更清楚。现在我们要创建一个子类,将name分配给其他东西。这样做的显而易见的方法(以及如何使用不具有常量属性的语言)将在调用super.init()之后分配它:

class Employee: Person {
    override init() {
        super.init()
        name = "Bob" // error: cannot assign to property: 'name' is a 'let' constant
    }
}

不。我们遇到了摘录中描述的情况。好吧,也许我们应该先分配它?

class Employee: Person {
    override init() {
        name = "Bob" // error: cannot assign to property: 'name' is a 'let' constant
        super.init()
    }
}

不。没有更好的。

啊!这是因为我们打电话给super.init()。我们不要叫它。

class Employee: Person {
    override init() {
        name = "Bob" // error: cannot assign to property: 'name' is a 'let' constant
    }
}

不......当他们说你不能这样做时,他们就意味着你不能这样做。您可以浏览更多内容,例如将课程更改为:

class Person {
    let name = "Alice"
}

你会发现你有同样的问题。您不能从子类中引入的方法分配超类中的let常量。

答案 1 :(得分:0)

您不是在修改代码中的现有常量 - 只创建类的新实例。如果你想看到一个错误来证明它,试试这个:

5663 KB/s (8971275 bytes in 1.546s) pkg: /data/local/tmp/app-release-unsigned.apk Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES] 

作为关于它无法被子类修改的一个例子:

let constanttest = ConstantTest(constant: "Hello")
constanttest.constant = "World" //Will not compile because "constant" is a constant

如果您对这些类的实例化感到困惑,这是使用class ConstantTest { let constant: String //<--- This is the constant you are unable to change init(constant: String) { self.constant = constant } func printConstant() { print(constant) } } let constantTest = ConstantTest(constant: "Hello") constantTest.printConstant() constantTest.constant = "World" //Will not compile class SubConstClass: ConstantTest { } let subTest = SubConstClass(constant: "hey") subTest.printConstant() subTest.constant = "Hi" //Will not compile (same as superclass) 的{​​{1}}和var的另一个简单示例:

let

答案 2 :(得分:0)

我只是觉得另一个答案没有理解你的困惑。虽然creeperspeak评论你here。您似乎无法理解与其实例之间的区别:

请参阅herehere

然后是以下示例:

let constanttest1 = ConstantTest(constant: "Hello") // This is an INSTANCE of ConstantTest class
let constanttest2 = ConstantTest(constant: "Hi") // ANOTHHER INSTANCE
let constanttest3 = ConstantTest(constant: "Bye") // another instance
let constanttest4 = ConstantTest(constant: "ByeBye") // another instance

var subTest = SubConstClass(constant: "hey") // This is an an instance of SubConstClass
var subTest2 = SubConstClass(constant: "heyhey") // This is an an instance of SubConstClass
var subTest3 = SubConstClass(constant: "HaHaHa") // This is an an instance of SubConstClass.

没有一个实例相互冲突。

相关问题