Polymorphism is a fundamental concept in object-oriented programming (OOP) that allows objects of different classes to be treated as objects of a common superclass. It enables a single interface to represent different underlying forms (data types). In Swift, polymorphism is achieved through inheritance and protocols.
Key Concepts
- Definition: Polymorphism means "many shapes" and allows methods to do different things based on the object it is acting upon.
- Types of Polymorphism:
- Compile-time Polymorphism: Achieved through method overloading and operator overloading.
- Runtime Polymorphism: Achieved through method overriding.
Method Overloading
Method overloading allows multiple methods in the same scope to have the same name but different parameters.
Example
class MathOperations {
func add(a: Int, b: Int) -> Int {
return a + b
}
func add(a: Double, b: Double) -> Double {
return a + b
}
}
let math = MathOperations()
print(math.add(a: 5, b: 3)) // Output: 8
print(math.add(a: 5.5, b: 3.3)) // Output: 8.8In this example, the add method is overloaded to handle both Int and Double types.
Method Overriding
Method overriding allows a subclass to provide a specific implementation of a method that is already defined in its superclass.
Example
class Animal {
func makeSound() {
print("Some generic animal sound")
}
}
class Dog: Animal {
override func makeSound() {
print("Bark")
}
}
class Cat: Animal {
override func makeSound() {
print("Meow")
}
}
let animals: [Animal] = [Dog(), Cat()]
for animal in animals {
animal.makeSound()
}In this example, the makeSound method is overridden in the Dog and Cat subclasses. When iterating through the animals array, the correct method is called based on the actual object type.
Protocols and Polymorphism
Protocols in Swift define a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. Classes, structs, and enums can conform to protocols to provide actual implementations of those requirements.
Example
protocol Shape {
func area() -> Double
}
class Circle: Shape {
var radius: Double
init(radius: Double) {
self.radius = radius
}
func area() -> Double {
return Double.pi * radius * radius
}
}
class Rectangle: Shape {
var width: Double
var height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
func area() -> Double {
return width * height
}
}
let shapes: [Shape] = [Circle(radius: 5), Rectangle(width: 4, height: 6)]
for shape in shapes {
print("Area: \(shape.area())")
}In this example, both Circle and Rectangle conform to the Shape protocol. The area method is implemented differently in each class, demonstrating polymorphism through protocols.
Practical Exercise
Exercise
Create a base class Vehicle with a method move(). Then, create two subclasses Car and Bicycle that override the move() method. Instantiate objects of Car and Bicycle and call the move() method on each.
Solution
class Vehicle {
func move() {
print("The vehicle is moving")
}
}
class Car: Vehicle {
override func move() {
print("The car is driving")
}
}
class Bicycle: Vehicle {
override func move() {
print("The bicycle is pedaling")
}
}
let myCar = Car()
let myBicycle = Bicycle()
myCar.move() // Output: The car is driving
myBicycle.move() // Output: The bicycle is pedalingCommon Mistakes and Tips
- Forgetting to use
overridekeyword: When overriding a method in a subclass, always use theoverridekeyword to avoid compilation errors. - Not calling the superclass method: If you need to call the superclass method within the overridden method, use
super.methodName(). - Misunderstanding protocol conformance: Ensure that all required methods and properties are implemented when conforming to a protocol.
Conclusion
Polymorphism is a powerful feature in Swift that allows for flexible and reusable code. By understanding and utilizing method overloading, method overriding, and protocols, you can create more dynamic and scalable applications. In the next section, we will explore another key concept in object-oriented programming: Protocols.
Swift Programming Course
Module 1: Introduction to Swift
- Introduction to Swift
- Setting Up the Development Environment
- Your First Swift Program
- Basic Syntax and Structure
- Variables and Constants
- Data Types
Module 2: Control Flow
Module 3: Functions and Closures
- Defining and Calling Functions
- Function Parameters and Return Values
- Closures
- Higher-Order Functions
Module 4: Object-Oriented Programming
Module 5: Advanced Swift
Module 6: Swift and iOS Development
- Introduction to iOS Development
- UIKit Basics
- Storyboards and Interface Builder
- Networking in Swift
- Core Data
- SwiftUI Basics
