Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

iOS Object-Oriented Swift 2.0 Class Inheritance Creating a Subclass

Which one is "right", or which one is not necessary?

I'm doing the Objective and creating the subclass of car. This is what I came up with in Playgrounds. It ran fine and the treehouse editor took it and said I passed. I felt it wasn't "correct" because during the video, Pasan said that when you create a subclass with a new variable that isn't in the main class and give it a default value, you don't have to do the whole initialization in the subclass.

First Run

class Vehicle 
{
    var numberOfDoors: Int
    var numberOfWheels: Int

    init(withDoors doors: Int, andWheels wheels: Int)
    {
        self.numberOfDoors = doors
        self.numberOfWheels = wheels
    }
}

class Car: Vehicle
{
    var numberOfSeats: Int = 4

    override init(withDoors doors: Int, andWheels wheels: Int)
    {
        super.init(withDoors: doors, andWheels: wheels)
    }
}

let someCar = Car(withDoors: 4, andWheels: 4)

This second one below is what I went back and did and took out the init part in the subclass. Treehouse editor took it and said I did it right. My question is, is the init in the top code just overkill and unnecessary? Or is it completely wrong and it just fell through the cracks?

Second Run

class Vehicle {
    var numberOfDoors: Int
    var numberOfWheels: Int

    init(withDoors doors: Int, andWheels wheels: Int)
    {
        self.numberOfDoors = doors
        self.numberOfWheels = wheels
    }
}

class Car: Vehicle
{
    var numberOfSeats: Int = 4

}

let someCar = Car(withDoors: 4, andWheels: 4)

2 Answers

Nathan Tallack
Nathan Tallack
22,158 Points

Your second one is good because you have a default value. But you would not be able to set that value on object creation because you do not have an initializer for it. You could always change it later of course.

With an init it would look like this.

class Vehicle {
    var numberOfDoors: Int
    var numberOfWheels: Int

    init(withDoors doors: Int, andWheels wheels: Int)
    {
        self.numberOfDoors = doors
        self.numberOfWheels = wheels
    }
}

class Car: Vehicle
{
    var numberOfSeats: Int

    init(withDoors doors: Int, andWheels wheels: Int, andSeats seats: Int) {
        self.numberOfSeats = seats
        super.init(withDoors: doors, andWheels: wheels)
    }

    override convenience init(withDoors doors: Int, andWheels wheels: Int) {
        let seats = 4
        self.init(withDoors: doors, andWheels: wheels, andSeats: seats)
    }
}

let someCar = Car(withDoors: 4, andWheels: 4)
let twoSeatCar = Car(withDoors: 2, andWheels: 2, andSeats: 4)

Now do keep in mind here, this is not likely the way you would implement an initializer. I am doing it this way to show you how some things work.

You can see in your Car subclass, for the init, we are asking for doors wheels and seats. The seats are set directly for the new property we have in this class, and the doors and wheels are passed up to the parent initializer in the super.init call.

Now you can see another convenience init function which we will use to override the primary. We use this one if we are too lazy to set the number of seats. You will not that it will set a local constant (used only within this init function of seats as 4. We then use the doors and wheels and that static local value for seats to call the default init function. In this way we are setting a default value for seats if we are too lazy to set it in the objec setup.

Vladimir Zivanovic
Vladimir Zivanovic
2,301 Points

Their is a syntax error in previous code in convenience init function,

self.init(withDoors: doors, andWheels: wheels, andSeats: seats)

It should be:

self.init(withDoors: doors, andWheels: wheels)

And for a local constant just insert:

let someCar = Car(withDoors: 4, andWheels: 4, andSeats: 4)

Steven Deutsch
Steven Deutsch
21,046 Points

Hey Ryan,

Your second solution IS correct and is much nicer code. Great job! I had to look this one up.

In certain situations, a subclass can inherit the initializers of its super class automatically. This is when you provide default values for the added properties to the subclass, and these two rules apply:

"Rule 1: If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.

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.”

Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2).” iBooks. https://itun.es/us/jEUH0.l