Initialization Question

Hi. This is fromt he iBook Swift 4.2.


On line 16, why is the numberOfSides: 1 even though, in it's superclass NameShape, it's already initialized to 0 and then on line 19, for the third time numberOfSides is initialized as 4?


Class NamedShape {
    var numberOfSides: Int = 0
    var name: String

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

    func simpleDescription() -> String {
       return "A shape with \(numberOfSides) sides."
    }
}
class Square: NamedShape {
    var sideLength: Double
  
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name, numberOfSides: 1) // I added numberOfSides: 1
        numberOfSides = 4
    }
  
    func area() -> Double {
        return sideLength * sideLength
    }
  
    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}


Thank you in advance.

Accepted Reply

Hi. How's the new year so far?


You're right, I forgot- I added those values 3 weeks ago when I was experimenting with it.

The one in the book only has this on line 16:


super.init(name: name)

numberOfSides = 4


I'll comment what I added as I master Swift, next time, coz' one forgets after some weeks.

Thanks.


The actual code on the Swift 4.2 book is:


class NamedShape {
     var numberOfSides: Int = 0
     var name: String

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

     func simpleDescription() -> String {
          return "A shape with \(numberOfSides) sides."
     }
}

class Square: NamedShape {
     var sideLength: Double

     init(sideLength: Double, name: String) {
          self.sideLength = sideLength
          super.init(name: name)
          numerOfSides = 4
     }

     func area() -> Double {
          return sideLength * sideLength
     }
     
     override func simpleDescription() -> String {
          return "A square with sides of length \(sideLength)."
     }
}


Init in Square (line 20) seems to have overriden the zero initialization on lin 02 without the keyword override?

Replies

I do not know where the code is shown in the book, but it is so strange as an initializer usage example and I guess it's written to demonstrate how Swift initializers can work.


First, the initializer `init(name:numberOfSides:)` of `NamedShape` does not set the value of the property `numberOfSides`, ignoring the argument `numberOfSides`. You should better not write something like this in your actual app.

Maybe this code is intended to show that you have no need to initialize all properties in your class when some properties have initial values.


Second, in the initializer `init(sideLength:name:)` of `Square`, `super.init(name: name, numberOfSides: 1)` is called (though, the value 1 is ignored and the property `numberOfSides` is initialized to 0) and the in the next line, `numberOfSides` is set to 4.

This is ridiculously misleading and hard to read, unless the purpose of the code is telling you that you can modify the value of properties after successful call to super.init .


But with all respects I mentioned above, I'm not sure it is a good example for Swift starters.


Does the book contain the right version of the two classes?

class NamedShape {
    var numberOfSides: Int
    var name: String
    
    init(name: String, numberOfSides: Int) {
        self.name = name
        self.numberOfSides = numberOfSides
    }

    //...
}

class Square: NamedShape {
    var sideLength: Double
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name, numberOfSides: 4)
    }

    //...
}


If no, I would not recommend it to starters...

Hi. How's the new year so far?


You're right, I forgot- I added those values 3 weeks ago when I was experimenting with it.

The one in the book only has this on line 16:


super.init(name: name)

numberOfSides = 4


I'll comment what I added as I master Swift, next time, coz' one forgets after some weeks.

Thanks.


The actual code on the Swift 4.2 book is:


class NamedShape {
     var numberOfSides: Int = 0
     var name: String

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

     func simpleDescription() -> String {
          return "A shape with \(numberOfSides) sides."
     }
}

class Square: NamedShape {
     var sideLength: Double

     init(sideLength: Double, name: String) {
          self.sideLength = sideLength
          super.init(name: name)
          numerOfSides = 4
     }

     func area() -> Double {
          return sideLength * sideLength
     }
     
     override func simpleDescription() -> String {
          return "A square with sides of length \(sideLength)."
     }
}


Init in Square (line 20) seems to have overriden the zero initialization on lin 02 without the keyword override?

I see. As I wrote in the previous comment, the changes are meaningful if the purpose is to see how initializers work in Swift.


Init in Square (line 20) seems to have overriden the zero initialization on lin 02 without the keyword override?


- Two initializers have different signatures `init(name:)` and `init(sideLength:name:)`

- Your line 20 is just an assignment, not any sort of declaration


You have no need to (and must not) put the keyword override in such cases.


An example when you need override,

if you want to re-declare the property `numberOfSides` as a computed property in Square, you need override.

class Square: NamedShape {
    override var numberOfSides: Int {
        get {
            return 4
        }
        set {
            assert(newValue == 4)
        }
    }
    var sideLength: Double
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
    }

    //...
}