Inheritance in Swift is one of the fundamental principles of object-oriented programming, derived from traditional OOP languages such as Objective-C and C++. However, Swift significantly restricts and simplifies this mechanism, focusing on type safety and code predictability.
In early OOP languages like C++ and Objective-C, inheritance was used to implement code reuse and create class hierarchies. Swift intentionally restricted this mechanism to avoid issues with multiple inheritance and convoluted hierarchies.
Classic implementations of inheritance are subject to several issues: implicit functionality addition through parent classes, difficulties in maintaining and testing code, as well as the diamond problem in multiple inheritance. In Swift, these problems are partially addressed by prohibiting multiple class inheritance.
Swift supports only single class inheritance. This means a class can inherit from only one parent class. For compositing behavior, it is recommended to use protocols and their extensions.
Example of simple inheritance:
class Animal { func speak() { print("Some sound") } } class Dog: Animal { override func speak() { print("Woof!") } } let animal: Animal = Dog() animal.speak() // "Woof!"
Key features:
super propertyCan you override a property declared as let in a subclass in Swift?
No. Properties declared with let cannot be overridden; they are constants. To allow overriding, use a var property with the override modifier.
Do structs or enums inherit any behavior in Swift?
No, only classes can inherit from each other. Structs (struct) and enums (enum) do not support inheritance but can implement protocols.
Can you create a class that cannot be inherited?
Yes, use the final modifier before the class declaration. Example:
final class Cat { func meow() { print("Meow!") } } // class Siamese: Cat {} // Compilation error
A developer created a deep class hierarchy for animals: Animal -> Mammal -> Carnivore -> Dog -> Bulldog. Each class adds new properties or methods.
Pros: Logic is divided by entities.
Cons: Hard to manage behavior changes in the hierarchy. Adding a new type of animal requires modifying several base classes, increasing the risk of errors.
Protocols (e.g., Sitter, Hunter) are used to differentiate between animals. Each class implements the required protocols instead of inheriting them through a multi-level hierarchy.
Pros: Behavior composition is more flexible, easily adding new types of animals without changing existing code.
Cons: Requires a better understanding of protocol-oriented programming, harder at the start.