← Swift EnglishChapter 08 of 13

Object-Oriented Programming

## Learning Objectives - Understand classes and structures - Master inheritance - Work with protocols - Learn initialization and deinitialization ## Classes vs Structures ### Structure (Value Type) ```swift struct Person { var name: String var age: Int func describe() { print("\(name) is \(age) years old") } } var person = Person(name: "Alice", age: 30) person.describe() ``` ### Class (Reference Type) ```swift class Vehicle { var brand: String var speed: Int = 0 init(brand: String) { self.brand = brand } func describe() { print("\(brand) at \(speed) km/h") } } let vehicle = Vehicle(brand: "Tesla") ``` ### Key Differences | Feature | Struct | Class | |---------|--------|-------| | Type | Value | Reference | | Inheritance | No | Yes | | Deinit | No | Yes | | Multiple references | No (copied) | Yes (shared) | ### Value vs Reference ```swift struct PointStruct { var x: Int var y: Int } var s1 = PointStruct(x: 1, y: 2) var s2 = s1 s2.x = 10 print(s1.x) // 1 (unchanged - copy!) class PointClass { var x: Int var y: Int init(x: Int, y: Int) { self.x = x self.y = y } } var c1 = PointClass(x: 1, y: 2) var c2 = c1 c2.x = 10 print(c1.x) // 10 (changed - same reference!) ``` ## Initialization ### Memberwise Init (Structures) ```swift struct Point { var x: Int var y: Int } let point = Point(x: 5, y: 10) ``` ### Custom Init (Classes) ```swift class BankAccount { var accountNumber: String var balance: Double init(accountNumber: String, initialBalance: Double) { self.accountNumber = accountNumber self.balance = initialBalance } convenience init() { self.init(accountNumber: "000", initialBalance: 0) } } ``` ### Property Initializers ```swift class Circle { var radius: Double let pi: Double = 3.14159 init(radius: Double) { self.radius = radius } var area: Double { return pi * radius * radius } } ``` ### Initializer Delegation ```swift class Rectangle { var width: Double var height: Double init(width: Double, height: Double) { self.width = width self.height = height } init(size: Double) { self.init(width: size, height: size) } init() { self.init(size: 0) } } let rect = Rectangle(size: 10) ``` ## Deinitialization ### deinit (Classes Only) ```swift class FileHandler { var fileName: String init(fileName: String) { self.fileName = fileName print("Opening \(fileName)") } deinit { print("Closing \(fileName)") } } if true { let handler = FileHandler(fileName: "data.txt") } // "Closing data.txt" printed when handler goes out of scope ``` ## Inheritance ### Basic Inheritance ```swift class Animal { var name: String init(name: String) { self.name = name } func speak() { print("...") } } class Dog: Animal { override func speak() { print("Woof!") } } class Cat: Animal { override func speak() { print("Meow!") } } let dog = Dog(name: "Buddy") dog.speak() // Woof! ``` ### Override Methods ```swift class Vehicle { func description() -> String { return "A vehicle" } } class Car: Vehicle { var wheels: Int = 4 override func description() -> String { return "A car with \(wheels) wheels" } } ``` ### Override Properties ```swift class Person { var name: String var age: Int var description: String { return "\(name), \(age) years old" } init(name: String, age: Int) { self.name = name self.age = age } } class Student: Person { var grade: String = "A" override var description: String { return super.description + " (Grade: \(grade))" } } ``` ### Final Classes Prevent inheritance: ```swift final class MathHelper { static func square(_ n: Int) -> Int { return n * n } } // class AdvancedMath: MathHelper {} // Error! ``` ## Access Control ### Access Levels | Level | Class | Subclass | Module | anywhere | |-------|-------|----------|--------|----------| | private | Yes | No | No | No | | fileprivate | Yes | No | Yes | No | | internal | Yes | Yes | Yes | No | | public | Yes | Yes | Yes | Yes | | open | Yes | Yes | Yes | Yes | ### Examples ```swift public class PublicClass { private var secret: String = "hidden" internal var name: String = "visible" public var data: Int = 0 } ``` ## Protocols ### Defining Protocols ```swift protocol Drawable { func draw() var color: String { get set } } protocol Printable { func printDescription() } ``` ### Conforming to Protocols ```swift class Circle: Drawable { var color: String var radius: Double init(color: String, radius: Double) { self.color = color self.radius = radius } func draw() { print("Drawing circle with radius \(radius)") } } ``` ### Protocol Inheritance ```swift protocol Shape { var area: Double { get } } protocol Printable { func printDescription() } class Rectangle: Shape, Printable { var width: Double var height: Double var area: Double { return width * height } init(width: Double, height: Double) { self.width = width self.height = height } func printDescription() { print("Rectangle: \(width) x \(height)") } } ``` ### Protocol Extensions ```swift protocol Summable { var total: Int { get } } extension Summable where Self: Numeric { var total: Int { return 0 } } ``` ## Static and Class Members ### Static Properties ```swift struct Counter { static var count = 0 init() { Counter.count += 1 } } let c1 = Counter() let c2 = Counter() print(Counter.count) // 2 ``` ### Class Properties ```swift class Configuration { class var defaultTimeout: Int { return 30 } } print(Configuration.defaultTimeout) // 30 ``` ## Methods ### Instance Methods ```swift class Counter { var count: Int = 0 func increment() { count += 1 } func increment(by amount: Int) { count += amount } func reset() { count = 0 } } ``` ### Mutating Methods (Structures) ```swift struct Point { var x: Int var y: Int mutating func moveBy(dx: Int, dy: Int) { x += dx y += dy } } var point = Point(x: 1, y: 2) point.moveBy(dx: 3, dy: 4) print(point) // Point(x: 4, y: 6) ``` ## Properties ### Stored Properties ```swift class Person { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } } ``` ### Computed Properties ```swift struct Rectangle { var width: Double var height: Double var area: Double { return width * height } var perimeter: Double { return 2 * (width + height) } } ``` ### Property Observers ```swift class ProgressTracker { var progress: Double = 0 { willSet { print("Will set to \(newValue)") } didSet { print("Did set from \(oldValue) to \(progress)") } } } ``` ### Lazy Properties ```swift class DataImporter { var fileName = "data.txt" // Heavy initialization } class DataManager { lazy var importer = DataImporter() init() { print("Manager initialized") } } let manager = DataManager() // importer not created yet print(manager.importer.fileName) // Now importer is created ``` ## Summary - Classes are reference types; structures are value types - Classes support inheritance; structures do not - Classes have deinit; structures do not - Use `init` for initialization; `deinit` for cleanup - Protocols define contracts; classes/structs conform - Access control: private, fileprivate, internal, public, open - Computed properties calculate values; stored properties hold values - `mutating` keyword needed for struct methods that modify properties - Lazy properties initialize on first access - Property observers (willSet/didSet) respond to changes

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →