0
0
Swiftprogramming~15 mins

Overriding methods and properties in Swift - Deep Dive

Choose your learning style9 modes available
Overview - Overriding methods and properties
What is it?
Overriding methods and properties means changing how a method or property works in a child class that it inherited from a parent class. It lets you customize or extend the behavior of the parent without rewriting everything. This is useful when you want similar objects to act differently in some ways. In Swift, you use the keyword 'override' to do this safely.
Why it matters
Without overriding, you would have to copy and change whole classes just to tweak small behaviors, which is slow and error-prone. Overriding lets you reuse code and keep your programs organized and flexible. It helps build apps that can grow and change easily, saving time and reducing bugs.
Where it fits
Before learning overriding, you should understand classes, inheritance, methods, and properties in Swift. After mastering overriding, you can explore advanced topics like polymorphism, protocol conformance, and design patterns that rely on customizing behavior.
Mental Model
Core Idea
Overriding lets a child class replace or extend a parent class’s method or property to change behavior while keeping the same interface.
Think of it like...
Imagine a family recipe passed down from parent to child. The child can follow it exactly or add their own twist by changing ingredients or steps, but it’s still recognized as the same recipe.
Parent Class
┌─────────────────────┐
│ methodA()           │
│ propertyX           │
└─────────┬───────────┘
          │ inherits
          ▼
Child Class (override)
┌─────────────────────┐
│ override methodA()  │
│ override propertyX  │
└─────────────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding inheritance basics
🤔
Concept: Inheritance allows a class to get methods and properties from another class.
In Swift, you create a class that inherits from a parent class using a colon. The child class automatically has all the parent's methods and properties. Example: class Animal { func sound() { print("Some sound") } } class Dog: Animal { } let dog = Dog() dog.sound() // prints "Some sound"
Result
The Dog class can use the sound() method from Animal without writing it again.
Understanding inheritance is key because overriding only works when a child class inherits from a parent.
2
FoundationMethods and properties in classes
🤔
Concept: Classes have methods (actions) and properties (data) that define their behavior and state.
A method is a function inside a class. A property is a variable or constant inside a class. Example: class Car { var color: String = "Red" func drive() { print("Driving") } } let car = Car() print(car.color) // Red car.drive() // Driving
Result
You can call methods and access properties on class instances.
Knowing what methods and properties are helps you understand what you can override.
3
IntermediateHow to override methods safely
🤔Before reading on: do you think you can override any method without special syntax in Swift? Commit to your answer.
Concept: Swift requires the 'override' keyword to change a method from a parent class, ensuring you don’t accidentally override something you didn’t mean to.
To override a method, write 'override' before the method in the child class. Example: class Animal { func sound() { print("Some sound") } } class Dog: Animal { override func sound() { print("Bark") } } let dog = Dog() dog.sound() // Bark
Result
The Dog class changes the sound() method to print "Bark" instead of "Some sound".
The 'override' keyword protects your code by making overriding explicit and intentional.
4
IntermediateOverriding properties with getters and setters
🤔Before reading on: do you think you can override a simple stored property directly in Swift? Commit to your answer.
Concept: You cannot override stored properties directly, but you can override computed properties by redefining their getter and setter.
Example: class Rectangle { var width: Double = 10 var height: Double = 5 var area: Double { return width * height } } class Square: Rectangle { override var area: Double { return width * width } } let square = Square() print(square.area) // 100
Result
The Square class overrides the computed property 'area' to calculate differently.
Understanding the difference between stored and computed properties is essential to know what can be overridden.
5
IntermediateUsing super to extend parent behavior
🤔Before reading on: do you think overriding always replaces the parent method completely? Commit to your answer.
Concept: You can call the parent’s method or property inside the override using 'super' to add extra behavior instead of replacing it fully.
Example: class Animal { func sound() { print("Some sound") } } class Dog: Animal { override func sound() { super.sound() print("Bark") } } let dog = Dog() dog.sound() // Output: // Some sound // Bark
Result
The Dog class adds to the parent's sound() method instead of replacing it.
Knowing how to use 'super' lets you build on existing behavior safely and clearly.
6
AdvancedOverriding property observers
🤔Before reading on: can you override property observers like willSet and didSet in a subclass? Commit to your answer.
Concept: Swift allows overriding property observers to run code when a property changes, even if the property is inherited.
Example: class Person { var age: Int = 0 { willSet { print("Age will change to \(newValue)") } } } class Employee: Person { override var age: Int { didSet { print("Age changed from \(oldValue) to \(age)") } } } let emp = Employee() emp.age = 30 // Output: // Age will change to 30 // Age changed from 0 to 30
Result
The Employee class adds a didSet observer to the inherited age property.
Overriding observers lets you react to changes in inherited properties without changing their core logic.
7
ExpertOverriding with final and dynamic keywords
🤔Before reading on: do you think all methods can be overridden freely in Swift? Commit to your answer.
Concept: Swift uses 'final' to prevent overriding and 'dynamic' to enable runtime method dispatch, affecting how overriding works internally.
final class or final methods cannot be overridden. This protects critical code. dynamic methods use Objective-C runtime to allow overriding and dynamic dispatch. Example: class Base { final func fixed() { print("Cannot override") } dynamic func changeable() { print("Can override") } } class Sub: Base { // override func fixed() {} // Error: cannot override final override func changeable() { print("Overridden") } } let obj: Base = Sub() obj.changeable() // Overridden
Result
final stops overriding; dynamic enables runtime overriding and polymorphism.
Understanding these keywords clarifies how Swift controls overriding for safety and flexibility.
Under the Hood
When you override a method or property in Swift, the compiler checks the 'override' keyword to confirm your intent. For methods marked 'dynamic', Swift uses the Objective-C runtime's message dispatch system, which looks up the method implementation at runtime, allowing polymorphism. For non-dynamic methods, Swift uses static dispatch, which is faster but less flexible. Stored properties cannot be overridden because they occupy fixed memory; only computed properties and observers can be overridden by redefining their accessors or observers. The 'final' keyword tells the compiler to prevent overriding, enabling optimizations and safety.
Why designed this way?
Swift was designed to be safe and fast. Requiring 'override' avoids accidental mistakes. Using 'final' lets developers protect important code and improve performance. The dynamic dispatch system supports interoperability with Objective-C and flexible polymorphism. Separating stored and computed properties avoids memory layout conflicts. These choices balance safety, speed, and flexibility.
Class Hierarchy
┌───────────────┐
│ Parent Class  │
│ ┌───────────┐ │
│ │ method()  │ │
│ │ property  │ │
│ └───────────┘ │
└──────┬────────┘
       │ inherits
       ▼
┌───────────────┐
│ Child Class   │
│ ┌───────────┐ │
│ │override   │ │
│ │method()   │ │
│ │override   │ │
│ │property   │ │
│ └───────────┘ │
└───────────────┘

Dispatch:
[static dispatch] <-- non-dynamic methods
[dynamic dispatch] <-- dynamic methods via Obj-C runtime
Myth Busters - 4 Common Misconceptions
Quick: Can you override a stored property directly in Swift? Commit to yes or no.
Common Belief:You can override any property, including stored ones, just by using 'override'.
Tap to reveal reality
Reality:Stored properties cannot be overridden in Swift; only computed properties and property observers can be overridden.
Why it matters:Trying to override stored properties causes compiler errors and confusion, blocking code reuse and customization.
Quick: Does omitting 'override' still override a method if the names match? Commit to yes or no.
Common Belief:If a child class defines a method with the same name as the parent, it automatically overrides it without needing 'override'.
Tap to reveal reality
Reality:Swift requires the 'override' keyword explicitly; omitting it causes a compile-time error to prevent accidental overrides.
Why it matters:This rule prevents bugs where a method is accidentally replaced, making code safer and easier to maintain.
Quick: Can you override a method marked 'final'? Commit to yes or no.
Common Belief:You can override any method regardless of modifiers if you want to change behavior.
Tap to reveal reality
Reality:Methods marked 'final' cannot be overridden; the compiler enforces this to protect critical code.
Why it matters:Ignoring 'final' leads to compile errors and misunderstanding of class design intentions.
Quick: Does overriding always replace the parent method completely? Commit to yes or no.
Common Belief:Overriding a method means the parent method is gone and replaced entirely.
Tap to reveal reality
Reality:You can call the parent method inside the override using 'super' to extend rather than replace behavior.
Why it matters:Not knowing this limits your ability to build on existing code and can lead to duplicated or broken logic.
Expert Zone
1
Overriding computed properties can change both getter and setter behavior independently, allowing fine control over property access.
2
Using 'final' on classes or methods not only prevents overriding but also enables the compiler to optimize calls with static dispatch.
3
Dynamic dispatch via 'dynamic' keyword introduces runtime overhead but is essential for Objective-C interoperability and some design patterns like KVO.
When NOT to use
Avoid overriding when you want to preserve strict behavior or when the parent class is designed to be immutable; instead, use composition or protocols. Also, do not override 'final' methods or classes. For simple behavior changes, consider adding new methods or properties rather than overriding.
Production Patterns
In real apps, overriding is used to customize UI components, extend framework classes, and implement polymorphic behavior. For example, UIView subclasses override layoutSubviews() to adjust layout. Property observers are overridden to react to state changes. Using 'super' calls is common to preserve base functionality while adding features.
Connections
Polymorphism
Overriding is a key mechanism that enables polymorphism by allowing different classes to respond differently to the same method call.
Understanding overriding helps grasp how polymorphism works, making code flexible and extensible.
Design Patterns (Template Method)
Overriding methods is central to the Template Method pattern, where a base class defines a skeleton algorithm and subclasses override steps.
Knowing overriding clarifies how design patterns use inheritance to customize behavior without changing overall structure.
Human Language Dialects
Just like overriding changes behavior in subclasses, dialects change language rules while keeping the same base language structure.
This cross-domain link shows how small changes on a common base can create rich variety, helping understand the power of overriding.
Common Pitfalls
#1Trying to override a stored property directly.
Wrong approach:class Parent { var name: String = "Parent" } class Child: Parent { override var name: String = "Child" // Error: Cannot override stored property }
Correct approach:class Parent { var name: String { return "Parent" } } class Child: Parent { override var name: String { return "Child" } }
Root cause:Misunderstanding that stored properties have fixed memory and cannot be overridden, unlike computed properties.
#2Omitting the 'override' keyword when overriding a method.
Wrong approach:class Parent { func greet() { print("Hello") } } class Child: Parent { func greet() { print("Hi") } }
Correct approach:class Parent { func greet() { print("Hello") } } class Child: Parent { override func greet() { print("Hi") } }
Root cause:Not knowing Swift requires explicit 'override' to prevent accidental method replacement.
#3Overriding a method marked 'final'.
Wrong approach:class Parent { final func fixed() { print("Cannot change") } } class Child: Parent { override func fixed() { print("Trying to override") } }
Correct approach:class Parent { final func fixed() { print("Cannot change") } } class Child: Parent { // No override allowed here }
Root cause:Ignoring the 'final' keyword which explicitly forbids overriding for safety and optimization.
Key Takeaways
Overriding lets child classes change or extend parent class methods and computed properties to customize behavior.
Swift requires the 'override' keyword to make overriding explicit and safe, preventing accidental mistakes.
Stored properties cannot be overridden; only computed properties and property observers can be customized in subclasses.
Using 'super' inside an override lets you add to parent behavior instead of replacing it completely.
The 'final' and 'dynamic' keywords control whether methods can be overridden and how they are dispatched at runtime.