Programming in Swift: Functions & Types

Jan 4 2022 · Swift 5.5, iOS 15, Xcode 13

Part 5: Protocols & Inheritance

41. Challenge: Initializers

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 40. Initializers Next episode: 42. Protocols

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Notes: 41. Challenge: Initializers

Update Notes: This course was originally recorded in 2019. It has been reviewed and all content and materials updated as of October 2021.

Transcript: 41. Challenge: Initializers

It’s class initializer Challenge Time! Find the challenge in the next page of the playground for this part of the course, and give the exercises your best shot. Pause the video now, and come back to compare solutions after you’re done.

The first part of the challenge was almost completely review. Defining a class, and giving it a property and method are concepts you’d gone over before.

39 class Animal {
  var name: String
    
  func speak() { }
}

And while an initializers in general aren’t new, either, the required keyword is.

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

And inheritance is new too.

class Dog: Animal {
  
}

My Dog kept track of tricks with a tricksLearnedCount property.

56 var tricksLearnedCount: Int

I used autocomplete to get me started on writing the initializer.

58 required init(name: String) {
    <#code#>
  }

Then, in proper order, I initializer the Dog’s property, then called super.init, and finished off by speaking.

58  tricksLearnedCount = 0
    super.init(name: name)
    speak()

Then I used autocomplete again to override the speak method.

override func speak() {
    <#code#>
  }

Then I used the name property in a dog-alized message!

65 print("Bow wow! My name is \(name)!")

I instantiated a dog named Shadow, who proceeded to greet me, in the console!

69 Dog(name: "Shadow")

Then I went for the second initializer. It was designated, but not required, or an override, so it just started with “init”.

64 init(name: String, tricksLearnedCount: Int) {

}

I copied over the code from the first initializer, and then changed the first line as appropriate.

65 self.tricksLearnedCount = tricksLearnedCount
    super.init(name: name)
    speak()

But then, I was able to get rid of some duplicated code, by doing the next part of the exercise. I changed the required initializer, from designated to convenience, and then I called my new designated initializer.

58 convenience required init(name: String) {
    self.init(name: name, tricksLearnedCount: 0)
    tricksLearnedCount = 0
    super.init(name: name)
    speak()
  }

At that point, the old code could be deleted.

58 convenience required init(name: String) {
    self.init(name: name, tricksLearnedCount: 0)
  }

And I create a Dog, with the new initializer.

Dog(name: "Chance", tricksLearnedCount: 3)

For the last exercise, I decided to use two different forms of defaulting. I skipped any sort of name parameter, but gave a default value to tricksLearnedCount, which is the most tricks an Int can represent.

extension Dog {
  convenience init(tricksLearnedCount: Int = .max) {
    
  }
}

Then, calling self.init (as you have to, in a convenience initializer), I used the name “Tramp”, but passed along tricksLearnedCount.

self.init(name: "Tramp", tricksLearnedCount: tricksLearnedCount)

Then I made a dog, using no arguments at all!

Dog().tricksLearnedCount

Good dog!