Swift Inheritance
Inheritance is a concept in object-oriented programming that allows creating a new class (derived class) from an existing class (base class). The derived class inherits all the properties and methods of the base class and can add new properties and methods to its own.
In Swift, the class
keyword is used to define a class that can be used as a base class for inheritance. To define a derived class, we use the subclass
keyword followed by the name of the base class.
Why Inheritance?
Inheritance allows us to reuse code and reduce code duplication. It also helps to create a hierarchical structure of classes, making code more organized and easier to maintain.
Swift Inheritance Syntax
In Swift, inheritance is achieved through the use of the class
keyword, followed by the name of the subclass, and then the superclass that the subclass inherits from, separated by a colon. The syntax for inheritance in Swift is as follows:
1class SubclassName: SuperclassName { 2 // class definition 3}
Here, SubclassName
is the name of the subclass, and SuperclassName
is the name of the superclass that the subclass inherits from.
Example: Swift Inheritance
Let's consider an example where we have a Person
class that has a property name
. We then create a subclass Employee
that inherits from the Person
class and adds a new property id
. Here's the code for the Person
class:
1class Person { 2 var name: String 3 4 init(name: String) { 5 self.name = name 6 } 7}
Now, we can create a subclass Employee
that inherits from the Person
class, like so:
1class Employee: Person { 2 var id: Int 3 4 init(name: String, id: Int) { 5 self.id = id 6 super.init(name: name) 7 } 8}
In this example, the Employee
class inherits the name
property from the Person
class and adds a new id
property. The Employee
class also has its own initializer, which takes both a name
and an id
. The super.init(name: name)
line calls the initializer of the superclass (Person
), passing in the name
parameter.
Is-A Relationship
Inheritance creates an "is-a" relationship between the derived class and the base class. For example, if we have a Person
class and a Student
class derived from Person
, we can say that a Student
is a Person
.
Methods Overriding in Swift Inheritance
The derived class can override the methods of the base class to provide its own implementation. To override a method, we use the override
keyword followed by the method definition.
1class Shape { 2 func area() -> Double { 3 return 0 4 } 5} 6 7class Circle: Shape { 8 var radius: Double 9 10 init(radius: Double) { 11 self.radius = radius 12 } 13 14 override func area() -> Double { 15 return Double.pi * radius * radius 16 } 17}
In the above example, Circle
is a subclass of Shape
. It overrides the area
method of the Shape
class to calculate the area of a circle.
Property Overriding in Swift Inheritance
Properties of the base class can also be overridden in the derived class. To override a property, we use the override
keyword followed by the property definition.
1class Person { 2 var name: String 3 4 init(name: String) { 5 self.name = name 6 } 7} 8 9class Student: Person { 10 var grade: String 11 12 init(name: String, grade: String) { 13 self.grade = grade 14 super.init(name: name) 15 } 16 17 override var name: String { 18 get { 19 return "Student: " + super.name 20 } 21 set { 22 super.name = newValue 23 } 24 } 25}
In the above example, Student
is a subclass of Person
. It overrides the name
property of the Person
class to add the prefix "Student: " to the name.
Overriding Property Getters and Setters
In the derived class, we can override the getter and/or setter of a property defined in the base class.
1class Employee { 2 var salary: Double { 3 get { 4 return 0 5 } 6 set { 7 print("Employee salary is set to \(newValue)") 8 } 9 } 10} 11 12class Manager: Employee { 13 override var salary: Double { 14 get { 15 return 10000 16 } 17 set { 18 super.salary = newValue 19 } 20 } 21}
In the above example, Manager
is a subclass of Employee
. It overrides the salary
property of the Employee
class to return a fixed value of 10000.
Overriding Property Observers
In Swift inheritance, you can also override property observers of the superclass properties in the subclass by providing your own custom implementation. However, if you override both getter and setter of the superclass property, you need to provide observers for that property as well.
Here's an example of how to override property observers in Swift:
1class Shape { 2 var numberOfSides = 0 3 var name: String { 4 willSet { 5 print("Changing shape's name to \(newValue)") 6 } 7 didSet { 8 print("Shape's name changed from \(oldValue) to \(name)") 9 } 10 } 11 12 init(name: String) { 13 self.name = name 14 } 15} 16 17class Square: Shape { 18 override var numberOfSides: Int { 19 didSet { 20 print("Square's number of sides is now \(numberOfSides)") 21 } 22 } 23 24 override var name: String { 25 willSet { 26 print("Changing square's name to \(newValue)") 27 } 28 didSet { 29 print("Square's name changed from \(oldValue) to \(name)") 30 } 31 } 32} 33 34let square = Square(name: "Square") 35square.numberOfSides = 4 36square.name = "My Square"
Output:
1Square's number of sides is now 4 2Changing square's name to My Square 3Square's name changed from Square to My Square
Final Property to Prevent Overriding
In Swift, you can also prevent a property or method from being overridden in the subclass by marking it as final
. When a property is marked as final
, it cannot be overridden in any of its subclasses.
Here's an example of how to use final
keyword in Swift:
1class Shape { 2 final var numberOfSides = 0 // cannot be overridden 3 var name: String 4 5 init(name: String) { 6 self.name = name 7 } 8} 9 10class Square: Shape { 11 // cannot override the 'numberOfSides' property 12 init(name: String, sides: Int) { 13 super.init(name: name) 14 numberOfSides = sides 15 } 16}
In this example, the numberOfSides
property is marked as final
, so it cannot be overridden in the subclass. The Square
class initializes the numberOfSides
property in its initializer without overriding it.