Open In App

Overriding Inherited Methods in Objective-C

Last Updated : 14 Jun, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Objective-C is an object-oriented programming language that is widely used in the development of iOS and Mac applications. Inheritance is an important concept in object-oriented programming that allows classes to inherit properties and behavior from other classes.

In Objective-C, inheritance is the mechanism by which one class acquires properties and behavior from another class. The class that inherits properties and behavior is called the subclass, and the class that provides the properties and behavior is called the superclass.

When a subclass inherits from a superclass, it can use all the properties and methods of the superclass as if they were its own. This means that the subclass can reuse code from the superclass and add its own functionality to it. Inheritance is a powerful mechanism for code reuse and can save developers a lot of time and effort.

To inherit from a superclass in Objective-C, you use the colon (:) notation in the interface declaration of the subclass. For example:

ObjectiveC




@interface MySubclass : MySuperclass


Need for Overriding Inherited Methods

While inheritance is a powerful mechanism for code reuse, sometimes the behavior of the superclass may not be suitable for the subclass. In such cases, the subclass needs to override the inherited methods of the superclass.

Overriding a method means that the subclass provides its own implementation of a method that has been inherited from the superclass. When the method is called on an instance of the subclass, the subclass’s implementation is used instead of the superclass’s implementation. For example, consider the following superclass:

ObjectiveC




@interface MySuperclass : NSObject
  
- (void)doSomething;
  
@end


And the following subclass that inherits from MySuperclass:

ObjectiveC




@interface MySubclass : MySuperclass
  
@end


If MySubclass needs to perform a different action when doSomething is called, it can override the method in the following way:

ObjectiveC




@implementation MySubclass
  
- (void)doSomething {
    // Do something different
}
  
@end


Now, when the doSomething method is called on an instance of MySubclass, the overridden implementation in MySubclass will be used instead of the implementation in MySuperclass.

Types of Inherited Methods

In Objective-C, you can override methods that are inherited from a superclass in order to provide custom behavior in a subclass. When a subclass inherits a method from its superclass, it can choose to override that method by providing its own implementation. This is called method overriding, and it allows you to customize the behavior of your classes and make them more flexible.

There are two types of inherited methods in Objective-C: class methods and instance methods. Class methods are methods that are called on the class itself, while instance methods are methods that are called on an instance of the class.

Syntax for Overriding Inherited Methods

To override an inherited method, you use the same method signature as the method you want to override. You can then provide your own implementation of the method inside the subclass. The syntax for overriding an inherited method in Objective-C is as follows:

ObjectiveC




- (returnType)methodName:(parameterType)parameterName {
    // Custom implementation
}


Let’s break this down:

Let’s break down the syntax:

  • -: This denotes that the method is an instance method. If you want to override a class method (a method belonging to the class itself), you would use + instead.
  • (returnType): This specifies the return type of the method. It can be any valid Objective-C data type or a custom class.
    methodName: This is the name of the method you want to override. It must match the name of the method you are overriding in the superclass.
  • :(parameterType)parameterName: These components specify the parameter(s) the method takes. Each parameter consists of a type and a name. If the method doesn’t take any parameters, you can omit this part.
  • {}: This encloses the body of the method, where you provide the custom implementation of the method.
    Here’s an example to illustrate how to override an inherited method:

Here’s an example to illustrate how to override an inherited method:

ObjectiveC




// Superclass
@interface Shape : NSObject
  
- (void)draw;
  
@end
  
@implementation Shape
  
- (void)draw {
    NSLog(@"Drawing a shape.");
}
  
@end
  
// Subclass
@interface Circle : Shape
  
- (void)draw;
  
@end
  
@implementation Circle
  
- (void)draw {
    [super draw]; // Calling the superclass implementation
    NSLog(@"Drawing a circle.");
}
  
@end


In the example above, we have a superclass Shape with a method draw, which simply logs “Drawing a shape.” The subclass Circle overrides the draw method and provides its own implementation. It calls the superclass implementation using [super draw] and then logs “Drawing a circle.”

When you create an instance of the Circle class and call the draw method, it will output:

Output

output

By providing a new implementation in the subclass, you effectively override the behavior of the inherited method.

Overriding Inherited Methods

Super Keyword

When you override a method in Objective-C, you can use the “super” keyword to call the implementation of the method in the superclass. This is useful when you want to modify the behavior of the inherited method while still retaining some of the original functionality.

Return Type and Arguments

The return type and arguments of an overridden method must match the return type and arguments of the original method. If the method you are overriding returns a value, you must provide a return statement in your implementation. If the method does not return a value, you can simply omit the return type.

Subtypes of Overriding Inherited Methods

There are three subtypes of overriding inherited methods in Objective-C: simple override, partial override, and complete override.

  1. Simple Override: A simple override involves providing a new implementation for an inherited method without modifying its behavior. This is the most common type of method overriding and is used to customize the behavior of a class without changing its basic functionality.
  2. Partial Override: A partial override involves modifying the behavior of an inherited method while still retaining some of its original functionality. This is useful when you want to customize the behavior of a method without completely changing its purpose.
  3. Complete Override:  A complete override involves replacing the inherited method with a completely new implementation. This is useful when you want to completely change the behavior of a method and provide new functionality. 

Examples of Overriding Inherited Methods

Simple Override Example:

ObjectiveC




#import <Foundation/Foundation.h>
  
@interface ParentClass : NSObject
  
- (void)printMessage;
  
@end
  
@implementation ParentClass
  
- (void)printMessage {
    NSLog(@"Hello, World!");
}
  
@end
  
  
@interface ChildClass : ParentClass
  
@end
  
@implementation ChildClass
  
- (void)printMessage {
    NSLog(@"Hello from ChildClass!");
}
  
@end
  
  
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        ParentClass *parent = [[ParentClass alloc] init];
        ChildClass *child = [[ChildClass alloc] init];
          
        [parent printMessage]; // Output: Hello, World!
        [child printMessage]; // Output: Hello from ChildClass!
    }
    return 0;
}


In this example, we have a parent class “ParentClass” and a child class “ChildClass”. The parent class has a method “printMessage” that prints a message “Hello, World!”. The child class overrides this method and prints a different message “Hello from ChildClass!” instead.
When the printMessage method is called on parentObj, it will log “Hello, World!” to the console because it uses the implementation of the method defined in the ParentClass.

However, when the printMessage method is called on childObj, it will log “Hello from ChildClass!” to the console instead, because it uses the implementation of the method defined in the ChildClass, which overrides the implementation defined in the ParentClass.

This demonstrates the concept of method overriding in Objective-C, where a subclass can provide its own implementation of a method defined in its superclass, allowing for greater flexibility and customization in the behavior of the subclass.

Output:

Output

 

Partial Override Example:

ObjectiveC




@interface ParentClass : NSObject
  
- (void)printMessage;
  
@end
  
@implementation ParentClass
  
- (void)printMessage {
    NSLog(@"Hello, World!");
}
  
@end
  
  
@interface ChildClass : ParentClass
  
@end
  
@implementation ChildClass
  
- (void)printMessage {
    [super printMessage];
    NSLog(@"Hello from ChildClass!");
}
  
@end


In this example, we have a parent class “ParentClass” and a child class “ChildClass”. The parent class has a method “printMessage” that prints a message “Hello, World!”. The child class overrides only a part of this method by calling the parent class method and then appending a message “Hello from ChildClass!”.

The ChildClass overrides the printMessage method of the parent class and adds an additional NSLog statement that outputs “Hello from ChildClass!” to the console. However, before doing so, it first calls the printMessage method of its parent class using the super keyword, which means that the “Hello, World!” message will also be printed to the console.

To see the output produced by this code, you can create instances of these classes and call their printMessage methods. Here’s an example:

ObjectiveC




ParentClass *parent = [[ParentClass alloc] init];
ChildClass *child = [[ChildClass alloc] init];
  
[parent printMessage];
[child printMessage];


The first message, “Hello, World!”, is produced by calling the printMessage method on an instance of ParentClass. The second message, “Hello, World!”, is produced by calling the printMessage method on an instance of ChildClass, which calls the printMessage method of its parent class before printing “Hello from ChildClass!”. Finally, the third message, “Hello from ChildClass!”, is produced by the NSLog statement in the printMessage method of ChildClass.

Note that because ChildClass inherits from ParentClass, it can use the printMessage method of the parent class directly by calling super printMessage. This allows it to reuse the existing functionality of the parent class while also adding its own functionality.

Output:

Output

 

Complete Override Example:

ObjectiveC




@interface ParentClass : NSObject
  
- (void)printMessage;
  
@end
  
@implementation ParentClass
  
- (void)printMessage {
    NSLog(@"Hello, World!");
}
  
@end
  
  
@interface ChildClass : ParentClass
  
@end
  
@implementation ChildClass
  
- (void)printMessage {
    NSLog(@"Hello from ChildClass!");
}
  
@end


In this example, we have a parent class “ParentClass” and a child class “ChildClass”. The parent class has a method “printMessage” that prints a message “Hello, World!”. The child class overrides this method completely by not calling the parent class method and instead printing a different message “Hello from ChildClass!”.

This Objective-C code defines two classes, ParentClass and ChildClass. ChildClass inherits from ParentClass.

ParentClass has one method called printMessage that simply logs the string “Hello, World!” to the console using NSLog.

ChildClass overrides the printMessage method of ParentClass and logs a different message, “Hello from ChildClass!” to the console using NSLog.

If you create instances of these classes and call their printMessage methods like so:

ObjectiveC




ParentClass *parent = [[ParentClass alloc] init];
ChildClass *child = [[ChildClass alloc] init];
  
[parent printMessage];
[child printMessage];


The first message is produced by calling the printMessage method on an instance of ParentClass. The second message is produced by calling the printMessage method on an instance of ChildClass, which overrides the parent class’s implementation and produces its own message instead.

Note that the ChildClass does not call the printMessage method of its parent class using super, so the output produced by the parent class’s implementation is not shown when calling child printMessage.

Output:

Output

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads