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 Class Inheritance Overriding Methods

Arun Kampadathil
Arun Kampadathil
2,429 Points

in this video its not very clear to me when to use "override" and when to use "super".

someone please explain how to use init() to initialize the properties of sub class and whey they are using the override to initialize properties of a subclassclass. How do I initialize the constant "isSuper" with init()

SuperEnemy: Enemy 
{
        let isSuper: Bool = true

    override init(x: Int, y: Int) {
        super.init(x: x, y: y)
        self.life = 50
    }
}

1 Answer

andren
andren
28,550 Points

If you wanted to be able to set isSuper when initializing the subclass you need to create an init method with that added as a parameter. That init method would not require the override keyword. Like this:

class SuperEnemy: Enemy { 
    // Do not initialize it here (that would cause issues since it is a constant)
    let isSuper: Bool
    // isSuper parameter added and override removed
    init(x: Int, y: Int, isSuper: Bool) { 
        // Subclass properties need to be initialized before `super` call
        self.isSuper = isSuper 
        super.init(x: x, y: y)
        self.life = 50
    }
}

The override keyword is required whenever you want to add a method with the same signature (matching name and parameters) as one that already exists in the class that you are inheriting from. Since the Monster class has an init method that takes x and y as parameters you need to use that keyword if you want to add an init method with the same signature to your SuperEnemy class. In the above code example you are not adding an init method with the same signature, since the list of parameter is different.

The super keyword is used to refer to the class that is being inherited from, in this case the Monster class (The name SuperEnemy is a tad misleading as this is not the class super refers to). So by calling super.init you are calling the init method of the Monster class. This is necessary because when instantiating a subclass you also need to instantiate the parent class, that is a requirement when inheriting classes.

Since the Monster class has an init method that takes an x and y argument you need to pass those along to it using the super.init call. However there is no requirement that the init methods of subclasses match their parent which is why you can add properties that are not found in the parent like I did in the above code examples. You just won't need to pass them along to the super.init call.

Edit: Improved code example.

Arun Kampadathil
Arun Kampadathil
2,429 Points

Thank for your detailed answer. I have one more doubt regarding this topic. What if subclass doesn't have any new properties to initialize, but still need to inherit the init method from superclass, does the init method in the subclass comes with "override" or just super.int. (simply asking) how does the init method looks like in a subclass when I dont have a any new properties to initialize?

andren
andren
28,550 Points

If you don't have any new properties or custom code you need to execute during the initialization of a subclass then you don't really have to worry about writing an init method at all. The subclass will inherit the parent's init method in the same way it does all of its other methods and properties.

Here is a simple example:

class Animal {
    let name: String
    let age: Int

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

class Cat: Animal {
    // No init method needs to be defined
    func printInfo() {
      print("The name of this cat is \(self.name) and its age is \(self.age).")
    }
}

let cat = Cat(name: "Oliver", age: 2)
cat.printInfo()

Even though no init method is defined in the Cat class you can still initialize it using the Animal class' init method, since it inherits that automatically from the Animal class. Calling the parent class' init method through super is only necessary when you are defining a custom init method in the subclasses.

To summarize, override is needed when defining a method that has the same signature as an existing method. This is not limit to init, it applies to all inherited methods. The super keyword is used to explicitly refer to the parent class, in the same way self refers to the object you are writing code in. It's generally used to call one of the parent methods, but it is usually only needed if you have overridden the method you are trying to call. If you have not overridden the method then you can call it as if it was a normal method defined inside the subclass, as you automatically inherit it from the parent class.

The main exception to that rule is the super.init call as that is always needed when writing an init method, regardless of whether it overrides the original method or not. This is because of the requirement to always initialize the super class when the child class is initialized. Without that call the parent class would not be initialized.