6 Replies
      Latest reply on Jan 13, 2019 6:13 PM by OOPer
      alvin777 Level 1 Level 1 (0 points)

        Hi. This is from the Apple's Swift 4.2 book.

         

        In line 02, numberOfSides was already initialized to 0. Why does numberOfSides still need to be initialized in line 19 when it already has an initialized value of 0?

         

         

        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 EquilateralTriangle: NamedShape {
            var sideLength: Double = 0.0
        
            init(sideLength: Double, name: String) {
                self.sideLength = sideLength
                super.init(name: name, numberOfSides: 1)
                //numberOfSides = 3
            }
        
            var perimeter: Double {
                get {
                     return 3.0 * sideLength
                }
                set {
                    sideLength = newValue / 3.0
                }
            }
        
            override func simpleDescription() -> String {
                return "An equilateral triangle with sides of length \(sideLength)."
            }
        }

         

        Thank you.

        God bless, Proverbs 31

        • Re: Initialized Twice?
          Claude31 Level 8 Level 8 (5,565 points)

          Isn't it the same question as

           

          https://forums.developer.apple.com/thread/112587

           

          The initialization with value of 0 at line 2 is just to have some value in the property (required by compiler) ; otherwise, you need to write it in an init(), or declare as optional.

           

          So this value is not to be used, it will always be replaced when you instanciate an instance.

          You have a convenience initializer that let you define the value to use for the instance.

           

          That's what you do on line 19.

           

          Note the sequence

          class EquilateralTriangle: NamedShape { 
              var sideLength: Double = 0.0 
           
              init(sideLength: Double, name: String) { 
                  self.sideLength = sideLength 
                  super.init(name: name, numberOfSides: 1) 
                  //numberOfSides = 3 
              } 

           

          1. Line 2 declares a property.

          All properties defined in the class must be set before you call super.init.

               Here it is done twice : by declaring = 0.0

               and by setting the value before super.

          But, if you simply wrote

               var sideLength : Double

          and call super first

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

           

          You would get a compiler error

          Property 'self.sideLength' not initialized at super.init call

           

          2. Line 6 calls the convenience initializer,

          to set name and numberOfSides. This is an initializer defined in superClass, so need to call super.init

           

          3. You could add a direct setting for the property at line 7:

                    self.numberOfSides = 3

           

          The subclass inherits its numberOfSides property from its super class, so you can use self.

          But you could also set it in the superclass (of the instance you create) by calling

               super.numberOfSides = 3

           

          Note: this code is just for illustration, as a triangle has 3 sides, not 1.

          • Re: Initialized Twice?
            OOPer Level 7 Level 7 (4,765 points)

            Once again, the code you have shown is not the same as in the Apple's Swift 4.2 book.

             

            Why have you added the initialization where Swift compiler does not claim to be needed?

              • Re: Initialized Twice?
                alvin777 Level 1 Level 1 (0 points)

                Hi. Thanks again for the reply. I checked again, you're right. Line 20 which is not commented out, line 19  and line 05 which doesn't have the numberOfsides prameter in the original- sorry. (I should put a comment where I changed it when I experiement so I don't get perplexed when I get back to it a few weeks later.)

              • Re: Initialized Twice?
                alvin777 Level 1 Level 1 (0 points)

                By the way, why didn't the Apple/Swift creators not include an automatic memberwise initializer for the classes (like how it is, in structs)? Is there an advantage of not having a the memberwise initializer as default/implicit? Not having it implicitly makes the code longer and prone to error- it's more of a disadvantage, it seems.

                  • Re: Initialized Twice?
                    OOPer Level 7 Level 7 (4,765 points)

                    Maybe you should visit forums.swift.org. And/or read the Deferred proposal SE-0018, especially its Rationale.

                    github.com/apple/swift-evolution/blob/master/proposals/0018-flexible-memberwise-initialization.md

                     

                    I do not understand why such a huge and complex compiler magic like Codable can be accepted but memberwise initializer for class cannot. But currently this is not a good place to say something to the designers of Swift.