Swift: OOP Fundamentals: A Beginner’s Guide
Swift: Advanced Classes
1. Introduction to Classes
In Swift, classes are fundamental building blocks of object-oriented programming (OOP). They allow you to model real-world entities, define their properties and behaviors, and organize your code efficiently.
2. Inheritance
One of the key principles of OOP is inheritance. This allows a new class (subclass) to inherit properties and behaviors from an existing class (superclass). Let’s illustrate this with an example:
// Base class
class Animal {
var name: String
init(name: String) {
self.name = name
}
func makeSound() {
print("Some generic animal sound")
}
}
// Subclass inheriting from Animal
class Dog: Animal {
override func makeSound() {
print("Woof!")
}
}
// Example usage
let genericAnimal = Animal(name: "Generic")
let dog = Dog(name: "Buddy")
genericAnimal.makeSound() // Outputs: Some generic animal sound
dog.makeSound() // Outputs: Woof!
3. Overriding
With overriding, a subclass can provide a specific implementation for a method or property that is already defined in its superclass. Here’s an example:
// Base class
class Vehicle {
func startEngine() {
print("Engine started")
}
}
// Subclass overriding startEngine
class Car: Vehicle {
override func startEngine() {
print("Car engine started")
}
}
// Example usage
let vehicle = Vehicle()
let car = Car()
vehicle.startEngine() // Outputs: Engine started
car.startEngine() // Outputs: Car engine started
4. Polymorphism
Polymorphism allows objects of different types to be treated as objects of a common type. This is often achieved through inheritance and overriding. Consider the following example:
// Common protocol
protocol Shape {
func calculateArea() -> Double
}
// Classes conforming to Shape
class Circle: Shape {
var radius: Double
init(radius: Double) {
self.radius = radius
}
func calculateArea() -> Double {
return Double.pi * radius * radius
}
}
class Square: Shape {
var sideLength: Double
init(sideLength: Double) {
self.sideLength = sideLength
}
func calculateArea() -> Double {
return sideLength * sideLength
}
}
// Example usage with polymorphism
let circle: Shape = Circle(radius: 5.0)
let square: Shape = Square(sideLength: 4.0)
print(circle.calculateArea()) // Outputs: 78.54
print(square.calculateArea()) // Outputs: 16.0
5. Initialization
Initialization is the process of preparing an instance of a class for use. It involves setting initial values for properties and performing any necessary setup. Here’s a simple example:
// Class with initialization
class Person {
var name: String
init(name: String) {
self.name = name
}
}
// Example usage
let person = Person(name: "John")
print(person.name) // Outputs: John
6. Class Hierarchies
Class hierarchies organize classes in a tree-like structure based on inheritance. A superclass is at the top, and subclasses extend from it. This promotes code reuse and logical organization:
// Base class
class Shape {
func draw() {
print("Drawing a shape")
}
}
// Subclasses forming a hierarchy
class Circle: Shape {
override func draw() {
print("Drawing a circle")
}
}
class Square: Shape {
override func draw() {
print("Drawing a square")
}
}
// Example usage
let shape: Shape = Circle()
shape.draw() // Outputs: Drawing a circle
7. Class Lifecycle in Memory
Understanding the class lifecycle in memory is crucial. It involves stages from creation to destruction, managed by Swift’s Automatic Reference Counting (ARC). Here’s a simple example:
class MyClass {
var data: String
init(data: String) {
self.data = data
print("Object created")
}
deinit {
print("Object deallocated")
}
}
// Example usage
var myObject: MyClass? = MyClass(data: "Hello")
myObject = nil // Outputs: Object deallocated
Mastering these fundamentals will pave the way for more advanced Swift programming. Happy coding!
https://github.com/abilgin88/SwiftCompendium/blob/main/Advanced%20Classes.playground/Contents.swift