30 Days of SwiftUI - Day 7: Cracking the Code with Swift Classes
๐️ Crafting Custom Types: Creating Your Own Classes
Classes are powerful building blocks in Swift that allow you to create custom data types with properties and methods.
Example:
class Car {
var brand: String
var year: Int
init(brand: String, year: Int) {
self.brand = brand
self.year = year
}
}
let myCar = Car(brand: "Tesla", year: 2024)
print(myCar.brand) // Output: Tesla
๐ Classes vs Structs: What's the Big Deal?
Feature | Structs | Classes |
---|---|---|
Value Type | Yes | No (Reference Type) |
Inheritance | No | Yes |
Deinitializer | No | Yes |
Memberwise Initializer | Yes (Auto-generated) | No |
Use structs for simple data models and classes when you need shared references or inheritance.
๐คท♂️ Why Don’t Classes Have a Memberwise Initializer?
Unlike structs, Swift doesn’t automatically create a memberwise initializer for classes because they are designed for more complex configurations.
Example:
class Laptop {
var brand: String
var model: String
init(brand: String, model: String) {
self.brand = brand
self.model = model
}
}
๐จ๐ฉ๐ฆ Unlocking Power: Understanding Inheritance
Inheritance lets one class inherit properties and methods from another, promoting code reuse.
Example:
class Vehicle {
var speed = 0
func accelerate() {
speed += 10
}
}
class Car: Vehicle {
func honk() {
print("Beep Beep!")
}
}
let car = Car()
car.accelerate()
print(car.speed) // Output: 10
car.honk() // Output: Beep Beep!
๐ When Should You Override a Method?
Use override
to customize inherited behavior in subclasses.
Example:
class Animal {
func speak() {
print("Animal makes a sound")
}
}
class Dog: Animal {
override func speak() {
print("Woof Woof!")
}
}
let dog = Dog()
dog.speak() // Output: Woof Woof!
๐ซ When to Declare a Class as final
Marking a class as final
prevents it from being subclassed, ensuring its behavior remains intact.
Example:
final class Account {
var balance = 1000
}
// Error: Cannot inherit from final class 'Account'
// class SavingsAccount: Account {}
๐ Customizing Initialization: Adding Initializers for Classes
Just like structs, classes can have custom initializers to manage setup logic.
Example:
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
๐ Copying Classes: Reference vs Value Types
Classes in Swift are reference types, meaning that copying a class instance creates a new reference to the same data.
Example:
class User {
var name: String = "Gati"
}
let user1 = User()
let user2 = user1
user2.name = "Shah"
print(user1.name) // Output: Shah
Both user1
and user2
point to the same instance in memory.
❓ Why Do Class Copies Share Data?
Since classes are reference types, they point to the same memory address rather than creating a new copy.
๐งน Cleaning Up: Deinitializers in Swift
Classes can have a deinit
method to handle cleanup when the object is being destroyed.
Example:
class FileHandler {
init() {
print("File opened")
}
deinit {
print("File closed")
}
}
var handler: FileHandler? = FileHandler() // Output: File opened
handler = nil // Output: File closed
๐ฅ Why Do Classes Have Deinitializers (and Structs Don’t)?
Since structs are value types, they get destroyed automatically when they go out of scope. Classes need deinit
to manually release resources when an instance is no longer needed.
⚙️ Managing Variables Inside Classes
Classes allow flexible handling of variables, even in constant class instances.
Example:
class Counter {
var value = 0
}
let counter = Counter()
counter.value = 10 // This works, even though `counter` is a constant
๐ค Why Can Class Variables Change in Constant Instances?
Since class instances are references, marking the instance as constant only prevents changing the reference itself, not the properties inside it.
✅ Checkpoint Challenge: Test Your Skills!
Question: Create a class Rectangle
with width
and height
properties, a method that calculates its area, and a deinitializer that prints a goodbye message.
Answer:
class Rectangle {
var width: Double
var height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
func area() -> Double {
return width * height
}
deinit {
print("Rectangle instance is being removed.")
}
}
var rect: Rectangle? = Rectangle(width: 5, height: 10)
print(rect?.area() ?? 0) // Output: 50
rect = nil // Output: Rectangle instance is being removed.
๐ Summary: Mastering Classes in Swift
✅ Classes enable complex data modeling with reference types.
✅ Inheritance simplifies code reuse and customization.
✅ Use final
to prevent subclassing when necessary.
✅ Remember, class instances share data, while structs create unique copies.
✅ Deinitializers ensure proper cleanup of resources.
Follow me on Linkedin: igatitech ๐๐๐
Comments
Post a Comment