2014-06-15 136 views
2

Swift编程语言的示例代码在第一行中没有调用super.init。这似乎是一种不安全的做法,因为继承的项目可以被父构造器覆盖,对吧?为什么Swift构造函数使用命名参数调用?

class EquilateralTriangle: NamedShape { 
    var sideLength: Double = 0.0 

    init(sideLength: Double, name: String) { 
     self.sideLength = sideLength 
     super.init(name: name) 
     numberOfSides = 3 
    } 

    var perimeter: Double { 
    get { 
     return 3.0 * sideLength 
    } 
    set { 
     sideLength = newValue/3.0 
    } 
    } 

    override func simpleDescription() -> String { 
     return "An equilateral triagle with sides of length \(sideLength)." 
    } 
} 
+0

是的,你是对的。在这种情况下,'sideLenght'将被默认值覆盖,并且您将失去用户的输入。你可以在这里阅读更多关于_initlaization_过程的信息:https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/Initialization.html – holex

+0

@holex'sideLength'将被* not *覆盖其默认值。在这种情况下,不需要指定默认值,但当您有多个初始化程序时,可能会派上用场,其中有些程序不需要知道“sideLength”。 –

回答

2

在初始化你必须调用super.init()之前做好充分准备的对象。这意味着,当您调用初始化程序的超级实现时,子类声明的所有属性都需要有一个值。

在调用super.init()之后,您可能会覆盖从超类继承的属性。 numberOfSides是继承的属性,因此在调用超级实现后被覆盖
numberOfSides =self.numberOfSides =在这个例子中是等价的。

为了把事情短:在子类中声明
1.属性必须在调用super.init()
2.继承属性必须调用super.init()

之后被覆盖之前设置的编译器将抛出一个错误对于第一种情况,但我不确定后者。

+0

这似乎是错误的,因为不应要求儿童班级知道家长的情况。所以父母可以重写孩子的性质似乎是违反直觉的。 – Boon

+0

我不明白你的问题,对不起。父级不能覆盖子级属性。你指的是什么? –

+1

对不起,我误解了你的观点1 - “在调用super.init之前必须设置子类声明的属性”。在super.init之前必须先准备好所有的子类属性的基本原理是什么? – Boon

相关问题