Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Intermediate Swift 2 Object Initialization Initializing Superclasses

Greg Kaleka
Greg Kaleka
39,021 Points

Why write out the second convenience initializer for Car?

Gabe Nadel, in this video, you write out a second convenience initializer for Car, but it is identical to Vehicle's convenience initializer. Since Car is a subclass of Vehicle, it already inherits this init method. In other words, even without writing this method, you could call Car() and get the exact same results.

Jhoan Arango
Jhoan Arango
14,575 Points

Greg:

The second convenience init, has a default property of 4 doors, that the super does not. And also, a convenience initializer can not be called from within another class, it must be called from within the same class.

He wrote this convenience init to illustrated how you can set default values. So when you create an instance of Car(), you have different options to choose from.

Greg Kaleka
Greg Kaleka
39,021 Points

Hi Jhoan,

I may not have been clear. I'm talking about the second convenience initializer for Car, which is the third initializer overall:

secondConvenienceInit.swift
convenience init() {
    self.init(name: "Unnamed")
}

This is the one that is identical to the superclass' init method. If we leave it out of the Car class definition, there is no impact that I can see. Check out the code below:

thisWorksJustFine.swift
class Vehicle {

    var name: String

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

    convenience init() {
        self.init(name: "Unnamed")
    }

}

class Car: Vehicle {

    let numberOfDoors: Int

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

    convenience override init(name: String) {
        self.init(name: name, numberOfDoors: 4)
    }

    // not including the empty convenience init, because we've already inherited it

}

let car = Car()    // calling the inherited empty convenience init

car.numberOfDoors  // returns 4
car.name           // returns "Unnamed"
Greg Kaleka
Greg Kaleka
39,021 Points

Additionally - to your point about not being able to call the superclass' convenience initializers - this is true if you're talking about calling it within the class definition. However, I'm talking about inheritance. You do inherit your superclass' convenience initializer, so long as you have implemented its designated initializer(s). From the docs:

Rule 2

If your subclass provides an implementation of all of its superclass designated initializersโ€”either by inheriting them as per rule 1, or by providing a custom implementation as part of its definitionโ€”then it automatically inherits all of the superclass convenience initializers.

Jhoan Arango
Jhoan Arango
14,575 Points

Greg :

You are right, I didn't see the other convenience initializer you were talking about until you pointed it out after. I thought you were talking about the one that sets the 4 doors by default. But yes, by inheriting from it's super class, my understanding is that he does inherits the convenience ini as well, unless I am wrong.

Would like to hear from Gabe Nadel himself.

Altho he did says in the video "Just for fun let's add another convenience initializer" probably to prove a point that you can have more than one convenience initializer.

1 Answer

Gabe Nadel
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Gabe Nadel
Treehouse Guest Teacher

You are both right!

Greg, yes, calling Car() will get us a new car instance with doors=4 and name = "unnamed"...

Jhoan, yes, I was writing this other convenience initializer "just for fun" to show we could add another.

In retrospect, I should have pointed out that why this wouldn't be necessary in our case, had it been a real app.

Thank you both for your feedback, it really helps make our content and community top notch.

Greg Kaleka
Greg Kaleka
39,021 Points

Thanks for answering! The rules around inheriting the various types of initializers are pretty tricky, so I get why you didn't get too in depth here. Appreciate the clarification. Really, I just wanted to make sure I wasn't missing something :)

Mert Kahraman
Mert Kahraman
12,118 Points

Hi Gabe,

I'm unsure about this concept though, hence I want to ask you: Given these two convenience init methods for Car class:

convenience override init(name: String) { self.init(name: name, numberOfDoors: 4) }

convenience init() { self.init(name: "Unnamed") }

On the second one, why didn't we also indlude that numberOfDoors should be 4? Aren't these two convenience init methods are totally unrelated with each other? How could the last init method make the numberOfDoors to be 4, without us indicating to do so?

I would sincerely appreciate if you can help me out with that, I'm totally lost here even though I re-watched the entire video.

Thanks! Mert