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 Object-Oriented Swift 2.0 Differentiating Between Objects Recap and Conclusions

How to Initialize New Values in a Subclass

On several occasions, the videos have shown this instructional:

  1. Provide values for properties of the subclass
  2. Once the subclass is initialized, provide values for properties of the base class.

Thus far, the tutorials have been clear on how to initialize new properties of the subclass if we set a default value, and also on how to initialize the base class. However, I do not think the tutorials have covered, and I would like to know, how to initialize a property of the subclass if I don't want to set a default value. Do I have to set a default value? Or can I initialize it as I would a constant or variable in the parent class?

I have tried to initialize with several different syntax iterations and can't find anything that works. Also the Apple page on Swift Initializing didn't seem to have the answer, at least not in language I could understand, or in an example I could copy.

For example: Here I have added a new variable to the subclass Profession, of parent class Person, and set its default to "Dr." What if I didn't want to set a default? What if I want to be able to input Strings other than "Dr." like "Professor" or "Chef" to the variable? How would I initialize this property?

class Person {
    let firstName: String
    let lastName: String

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }

    func getFullName() -> String {
        return "\(firstName) \(lastName)"
    }
}


class Profession: Person {

    var profession: String = "Dr."

    override func getFullName() -> String {
        return "\(profession) \(lastName)"
    }

}

let someDoctor = Doctor(firstName: "Sam", lastName: "Smith")

someDoctor.getFullName()

4 Answers

John Ambrose
John Ambrose
7,216 Points

Hi Sonia! So here are 2 ways to go about this. The first and not terribly good way is to set an empty value for the Profession Class, like so.

class Profession: Person {

    var profession: String = ""

    override func getFullName() -> String {
        return "\(profession) \(lastName)"
    }

}

Because Profession is a Class, it must have a value set when it is initialized. In the above example, you provide an empty string as the initialized value. Since it is a variable you can then later change it by calling ".profession" on the initialized Class. However, as i mentioned this isn't (in my opinion) the best way. This way actually can make someone forget there is a profession variable there.

Rodrigo's way is much better but there is some additional coding necessary. See below:

class Profession: Person {

    var profession: String

    init (firstName: String, lastName: String, profession: String) {
        self.profession = profession
        super.init(firstName: firstName, lastName: lastName)
    }

    override func getFullName() -> String {
        return "\(profession) \(lastName)"
    }

}

if you enter this Sub Class into Xcode with your current Super Class, you'll be able to create an instance of Profession, and when you initialize it you are forced to set a profession..

Now there is something special here to note that I figured out while hacking away at your questions.

Order matters in the init function. Go ahead and flip positions of "self. profession..." and "super.init..." code. Xcode will give you an error saying that the profession property is not initialized.

Since the super.init function is ALSO and initializer, it basically ends the initialization. So the minute you run the super.init you are basically starting a fully formed initialization block. And since you don't have the profession yet set, you get an error. But once you set that property BEFORE the "super.init" call, you're golden!

Hope all of that made sense. I was banging my head a little bit trying to figure out how to get it to work because from everything I've seen so far Rodrigo's method should have worked, but I kept getting errors.

Rodrigo Chousal
Rodrigo Chousal
16,009 Points

The answer is, you wouldn't. You wouldn't initialise this variables because instead of setting a default variable, you'd just do this instead:

var profession: String // Here, you're just declaring the variable for later use

And then set it to whatever you want later in the program.

Hope this helps.

Rodrigo Chousal
Rodrigo Chousal
16,009 Points

Hey Sonia,

First off, it's not very good design to have a profession class, as a profession is a property of Person. Therefore, it should be a variable inside the Person class. But to answer your question, you can simply create an instance of type Profession and then change this value like so:

someProfession = Profession(firstName: "Sam", lastName: "Smith")
someProfession.profession = "Engineer"
someProfession.getFullName() // Returns "Engineer Smith", using your code

However, as I said, this is not optimal design and I would change your code to something more like this:

class Person1 {
    let firstName: String
    let lastName: String

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }

    func getFullName() -> String {
        return "\(firstName) \(lastName)"
    }
}


class Profession: Person1 {

    var profession: String = "Dr."

    override func getFullName() -> String {
        return "\(profession) \(lastName)"
    }

}

let someDoctor = Profession(firstName: "Sam", lastName: "Smith")
someDoctor.profession = "Engineer"
someDoctor.getFullName()

Or even better,

class Person1 {
    let firstName: String
    let lastName: String
    var profession: String = "Dr."

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }

    func getFullName() -> String {
        return "\(firstName) \(lastName)"
    }

    func getFullNameWithProfession() -> String {
        return "\(profession) \(lastName)"

    }
}

let someEngineer = Person1(firstName: "Sam", lastName: "Smith")
someEngineer.profession = "Engineer"
someEngineer.getFullName() // "Sam Smith"
someEngineer.getFullNameWithProfession() // "Engineer Smith"

Hope this helps, Rodrigo

Hi Rodrigo, Thank you for getting back to me.

I understand your qualms about using the class Profession. However, I actually was just taking this code from a code challenge. I changed the class from Doctor to Profession because I wanted to indicate that I am interested in having more than one option for the person's profession.

These solutions unfortunately do not solve the problem I was having, as I am interested in a way to achieve the same end WITHOUT setting a default value of "Dr." to profession.

To reiterate what I asked initially: Here I have added a new variable to the subclass Profession, of parent class Person, and set its default to "Dr." What if I didn't want to set a default? What if I want to be able to input Strings other than "Dr." like "Professor" or "Chef" to the variable? How would I initialize this property?