”;
Overriding is a very common concept in object-oriented programming languages. Using overriding we are allowed to re-implement a method or property of a superclass in a subclass. It allows us to extend the behaviour of inheritance. While overriding the method or property we are providing a new implementation in the subclass instead of using the the implementation in the superclass. In Swift, we can override the method or the property of the superclass.
Access to Superclass Methods, Properties and Subscripts
The ”super” keyword is used as a prefix to access the methods, properties and subscripts declared in the superclass.
Overriding | Access to methods, properties and subscripts |
---|---|
Methods | super.somemethod() |
Properties | super.someProperty() |
Subscripts | super[someIndex] |
Rules for overriding in Swift
Following are some rules you should follow while overriding −
-
The overridden method or property in the subclass must have the same signature(name, parameter and return type) as they are in the superclass.
-
Use the super keyword to call the overridden implementation from the superclass in the overriding method.
-
Use the override keyword to override properties. We can override both stored and computed properties.
-
The access level of an overriding method or property cannot be more restrictive than the access level of the overridden method or property in the base class. You are not allowed to override a public method with a private method. So always check the access modifier before overriding.
Methods Overriding in Swift
In Swift, we are allowed to override methods. The overriding method means a subclass can provide a different implementation for a method that is already defined in the base class. Or we can say that we can customize the behaviour of a superclass method in the subclass.
The overridden method in the subclass must have the same signature(name, parameter and return type) as the base class and the compiler will determine which method is called according to the type of object. Also, the access level of the overridden method in the subclass must be the same or more permissive than the access level of the method in the superclass.
The override method is defined by using the override keyword in the subclass. This keyword is placed before starting the function definition. It tells the compiler that the method will override the method of the superclass. If we do not specify the override keyword then the compiler will give us the error.
Syntax
Following is the syntax for method overriding −
override func methodName(Parameters) -> returntype { Statement return parameters }
Example
Swift program for method overriding.
// Super class class cricket { // Method func show() { print("Welcome to Swift Super Class") } } // Sub class class tennis: cricket { // Overriden Method override func show() { print("Welcome to Swift Sub Class") } } // Creating instance of subclass let tennisinstance = tennis() // Accessing the override method tennisinstance.show()
Output
It will produce the following output −
Welcome to Swift Sub Class
Property Overriding
Swift supports property overriding. Just like method overriding, property overriding also provides a way for a subclass to customize the implementation of the properties that are already defined in the base class. We can say that using property overriding, we can provide our own getter and setter for that property or add property observers, which enables the overriding property to observe when the property value changes.
The type of the overridden property in the subclass must have the same name and type as the property in the base class. So that the compiler will determine which property(either the superclass property or overridden property) is called according to the type of object. The access level of the overridden method in the subclass must be similar or more permissive than the access level of the property in the superclass.
The override property is defined by using the override keyword in the subclass. This keyword is placed before starting the property definition. It tells the compiler that the property will override the property of the superclass. If we do not specify the override keyword, then the compiler will give us the error.
Syntax
Following is the syntax for property overriding −
override var propertyName: type{ // Statement }
Example
Swift program for property overriding.
// Superclass class mySuperClass { // Property var language: String{ return "C++" } } // Subclass class mySubClass: mySuperClass { // Override Property override var language: String{ return "Swift" } } // Creating an instance of a subclass let obj = mySubClass() // Accessing the overridden property print(obj.language)
Output
It will produce the following output −
Swift
Overriding Property Getters and Setters
Swift allows the user to override the getter and setter of the subclass property, whether the property is stored or computed. The name and the type of the overriding property must be the same as the property present in the base case. So that the compiler knows that you are overriding the property of the base class.
In Swift, we are allowed to represent the read-only inherited property as a read-write property by providing both a getter and setter in the subclass while overriding. Whereas we are not allowed to represent the read-write-only inherited property as read-only property. When setter is defined for overriding property the user has to define getter too. If we do not wish to modify the value of the inherited property in the overriding getter, then we can pass the inherited value using ”super.PropertyName” from the getter, where PropertyName represents the name of the overriding property.
Example
Swift program for overriding property getter and setter.
// Base Class class Circle { var radius = 12.5 // Property with getter var area: String { return "of rectangle for (radius) " } } // Subclass class Rectangle: Circle { var print = 7 // Overriding the getter override var area: String { return super.area + " is now overridden as (print)" } } // Creating instance let rect = Rectangle() // Accessing the properties rect.radius = 25.0 rect.print = 3 print("Radius (rect.area)")
Output
It will produce the following output −
Radius of rectangle for 25.0 is now overridden as 3
Overriding Property Observers
When a new property needs to be added for an inherited property, ”property overriding” concept is introduced in Swift 4. This notifies the user when the inherited property value is altered. But overriding is not applicable for inherited constant stored properties and inherited read-only computed properties.
Example
class Circle { var radius = 12.5 var area: String { return "of rectangle for (radius) " } } class Rectangle: Circle { var print = 7 override var area: String { return super.area + " is now overridden as (print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("Radius (rect.area)") class Square: Rectangle { override var radius: Double { didSet { print = Int(radius/5.0)+1 } } } let sq = Square() sq.radius = 100.0 print("Radius (sq.area)")
Output
When we run the above program using playground, we get the following result −
Radius of rectangle for 25.0 is now overridden as 3 Radius of rectangle for 100.0 is now overridden as 21
Preventing Overriding in Swift
Swift provides a special keyword to prevent methods, properties, subscripts, or even classes from being overridden and this keyword is known as the final keyword. The final keyword explicitly indicates that the specified method, property, subscript or class can not be overridden by the subclasses. If the user still tries to attempt overriding, then the compiler will give errors.
The final keyword is always used before the declaration of the method, property, subscript or class.
Syntax
Following is the syntax for preventing overriding −
// For methods final func methodName(Parameters) -> returntype{} // For property final var propertyName : type // For subscript final subscript(index: Int)->Elemnt{} // For class final class className{}
Example
Swift program to prevent overriding.
// Base class final class Circle { final var radius = 12.5 var area: String { return "of rectangle for (radius) " } } // Sub class class Rectangle: Circle { var print = 7 override var area: String { return super.area + " is now overridden as (print)" } } // Creating instance let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("Radius (rect.area)")
Error
main.swift:12:17: error: property overrides a ''final'' property override var area: String { ^ main.swift:4:8: note: overridden declaration is here var area: String { ^ main.swift:10:7: error: inheritance from a final class ''Circle'' class Rectangle: Circle { ^ main.swift:21:17: error: ambiguous use of ''area'' print("Radius (rect.area)") ^ main.swift:12:17: note: found this candidate override var area: String { ^ main.swift:4:8: note: found this candidate var area: String { ^
Since the superclass is declared as ”final” and its data types are also declared as ”final” the program won”t allow to create subclasses further and it will throw errors.
”;