Swift Inheritance: Syntax, Usage, and Examples
Swift inheritance lets you create a new class by extending an existing one. This helps you reuse code and organize your program efficiently. With inheritance, you can share properties and methods between related objects without rewriting the same code.
How to Use Inheritance in Swift
To make a class inherit from another, use a colon :
followed by the name of the parent class.
swift
class Animal {
var name: String
init(name: String) {
self.name = name
}
func makeSound() {
print("Some generic animal sound")
}
}
class Dog: Animal {
func bark() {
print("Woof!")
}
}
let dog = Dog(name: "Buddy")
dog.makeSound() // Output: Some generic animal sound
dog.bark() // Output: Woof!
Here, Dog
inherits from Animal
. This means Dog
gets the name
property and the makeSound
method from Animal
without needing to redefine them.
Overriding Methods
If you need a subclass to have a different behavior than its parent, you can override a method using override
.
swift
class Cat: Animal {
override func makeSound() {
print("Meow!")
}
}
let cat = Cat(name: "Whiskers")
cat.makeSound() // Output: Meow!
Preventing Inheritance
If you want to stop a class from being inherited, mark it as final
.
swift
final class Bird {
var canFly = true
}
// The following would cause an error:
// class Sparrow: Bird { }
When to Use Inheritance in Swift
Avoiding Code Duplication
If multiple classes share the same properties or methods, inheritance helps you avoid writing the same code over and over.
swift
class Vehicle {
var speed = 0
func accelerate() {
speed += 10
}
}
class Car: Vehicle {
var fuelLevel = 100
}
let myCar = Car()
myCar.accelerate()
print(myCar.speed) // Output: 10
Specializing Behavior
You can use inheritance to define general behavior in a parent class and then specialize it in subclasses.
swift
class Employee {
func work() {
print("Working...")
}
}
class Engineer: Employee {
override func work() {
print("Solving technical problems...")
}
}
let engineer = Engineer()
engineer.work() // Output: Solving technical problems...
Organizing Related Objects
Inheritance makes it easier to structure your program when you have related objects.
swift
class Shape {
func draw() {
print("Drawing a shape")
}
}
class Circle: Shape {
override func draw() {
print("Drawing a circle")
}
}
let circle = Circle()
circle.draw() // Output: Drawing a circle
Examples of Inheritance in Swift
Using Superclass Properties
A subclass automatically gets the properties of its parent class.
swift
class Animal {
var species: String
init(species: String) {
self.species = species
}
}
class Dog: Animal {
func describe() {
print("This is a \(species)")
}
}
let myDog = Dog(species: "Golden Retriever")
myDog.describe() // Output: This is a Golden Retriever
Calling Superclass Methods
If you need to call a method from the parent class inside an overridden method, use super
.
swift
class Parent {
func greet() {
print("Hello from Parent")
}
}
class Child: Parent {
override func greet() {
super.greet() // Calls the parent method
print("Hello from Child")
}
}
let child = Child()
child.greet()
// Output:
// Hello from Parent
// Hello from Child
Initializing Subclasses
If your subclass has additional properties, you must initialize them before calling the parent class’s initializer.
swift
class Person {
var name: String
init(name: String) {
self.name = name
}
}
class Student: Person {
var grade: Int
init(name: String, grade: Int) {
self.grade = grade
super.init(name: name)
}
}
let student = Student(name: "Emma", grade: 10)
print(student.name) // Output: Emma
print(student.grade) // Output: 10
Learn More About Inheritance in Swift
Protocol Inheritance
Unlike classes, Swift protocols allow multiple inheritance. You can make a protocol inherit from one or more protocols.
swift
protocol Readable {
func read()
}
protocol Writable {
func write()
}
protocol Document: Readable, Writable {}
class Book: Document {
func read() {
print("Reading a book")
}
func write() {
print("Writing notes in the book")
}
}
let myBook = Book()
myBook.read() // Output: Reading a book
myBook.write() // Output: Writing notes in the book
Multiple Inheritance in Swift
Swift doesn’t allow multiple class inheritance, but you can combine behaviors using protocol composition.
swift
protocol Driver {
func drive()
}
protocol Mechanic {
func repair()
}
class RaceCarDriver: Driver, Mechanic {
func drive() {
print("Driving at high speed")
}
func repair() {
print("Fixing the car")
}
}
let racer = RaceCarDriver()
racer.drive() // Output: Driving at high speed
racer.repair() // Output: Fixing the car
Structs and Inheritance
Unlike classes, structs don’t support inheritance. If you need similar behavior, use protocol conformance.
swift
protocol Identifiable {
var id: String { get }
}
struct User: Identifiable {
var id: String
}
let user = User(id: "12345")
print(user.id) // Output: 12345
Enum Inheritance
Swift enums don’t support inheritance, but you can extend them with methods.
swift
enum Status {
case success
case failure
func message() -> String {
switch self {
case .success:
return "Operation succeeded"
case .failure:
return "Operation failed"
}
}
}
let status = Status.success
print(status.message()) // Output: Operation succeeded
Best Practices for Using Inheritance
- Use inheritance only when there’s a clear “is-a” relationship. A
Car
is aVehicle
, but aDriver
is not aVehicle
. - Prefer protocols when possible. If multiple unrelated classes need the same behavior, protocols are more flexible than deep inheritance chains.
- Minimize method overriding. Too many overrides can make your code harder to follow.
- Mark methods as
final
if you don’t want subclasses to override them. This prevents unintended behavior changes. - Call
super.init()
properly. Always initialize subclass properties before calling the parent class initializer.