[Swift Apple ] Swift 클래스(Class) 고급 사용법

오늘은 Swift의 클래스(Class) 고급 사용법에 대해 알아보겠습니다. 기초적인 클래스 정의를 넘어서, 실제 앱 개발에서 활용할 수 있는 상속(Inheritance), 다형성(Polymorphism), 메모리 관리(ARC),  그리고 고급 기능인 클래스 확장(Extension), 타입 프로퍼티/메서드, final 키워드 등  클래스를 제대로 활용할 수 있는 심화 내용을 정리해드릴게요!


[Swift Apple ] Swift 클래스(Class) 고급 사용법
[Swift Apple ] Swift 클래스(Class) 고급 사용법




🚀 Swift 클래스(Class) 고급 사용법

– 객체지향 설계와 메모리 관리까지 완벽하게!

Swift의 클래스는 단순한 데이터 묶음이 아닙니다. 복잡한 앱 구조를 효율적으로 설계하고 관리할 수 있는 강력한 도구입니다. 이번 글에서는 클래스의 심화 개념을 하나씩 살펴보겠습니다.


1️⃣ 상속 (Inheritance) – 코드 재사용과 확장성

클래스의 가장 큰 특징 중 하나는 상속입니다. 부모 클래스의 기능을 자식 클래스가 물려받아 확장하거나 변경할 수 있어요.


예제: 상속과 메서드 오버라이딩

class Animal {
    func sound() {
        print("동물이 소리를 냅니다.")
    }
}

class Cat: Animal {
    override func sound() {
        print("야옹~")
    }
}

let myCat = Cat()
myCat.sound()  // 야옹~

  • override 키워드로 부모 메서드를 재정의할 수 있어요.

  • 코드 재사용과 확장성을 동시에!






2️⃣ 다형성 (Polymorphism) – 하나의 타입으로 다양한 객체 관리


다형성은 부모 타입으로 여러 자식 클래스를 하나처럼 관리할 수 있게 해줍니다.

let animals: [Animal] = [Cat(), Dog(), Animal()]
for animal in animals {
    animal.sound()   // 각 클래스에 맞게 다른 소리 출력
}

  • 같은 메서드 호출이지만, 객체에 따라 다르게 동작!



3️⃣ 클래스의 메모리 관리 (ARC)와 순환 참조(Retain Cycle)


Swift의 클래스는 참조 타입이라 자동으로 메모리를 관리하는

ARC (Automatic Reference Counting) 가 적용돼요.


하지만 서로가 서로를 참조하면 메모리 누수가 발생할 수 있습니다.

이를 순환 참조(Retain Cycle) 라고 해요.


예제: 순환 참조 방지 (weak 사용)

class Person {
    var name: String
    weak var pet: Pet?   // 약한 참조

    init(name: String) {
        self.name = name
    }
}

class Pet {
    var owner: Person?

    init(owner: Person) {
        self.owner = owner
    }
}

  • weak 또는 unowned 키워드로 순환 참조 방지

  • 주로 delegate 패턴에서 사용됨





4️⃣ 타입 프로퍼티 & 타입 메서드 (Static / Class)


클래스 전체가 공유하는 변수와 메서드를 만들 수 있어요.

class Counter {
    static var totalCount = 0

    init() {
        Counter.totalCount += 1
    }

    static func showCount() {
        print("총 생성된 인스턴스: \(totalCount)")
    }
}

let c1 = Counter()
let c2 = Counter()
Counter.showCount()   // 총 생성된 인스턴스: 2

  • 인스턴스가 아닌 클래스 자체에 속하는 속성/메서드






5️⃣ 클래스 확장 (Extension) – 기능 추가하기


기존 클래스에 기능을 추가할 수 있어요.

코드를 분리하거나, 외부 라이브러리 클래스를 확장할 때 유용합니다.

class Circle {
    var radius: Double = 0
}

extension Circle {
    var area: Double {
        return 3.14 * radius * radius
    }
}






6️⃣ final 키워드 – 상속 금지 & 오버라이딩 방지


클래스를 설계할 때, 더 이상 상속되지 않게 막고 싶다면 final 키워드를 사용합니다.

final class Settings {
    static let version = "1.0"
}

  • 보안, 안정성을 위해 상속을 제한할 때 사용

  • 메서드나 프로퍼티에도 적용 가능





7️⃣ Convenience Initializer (편의 이니셜라이저)


클래스에서는 여러 초기화 방법을 제공할 수 있어요.

class User {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    convenience init(name: String) {
        self.init(name: name, age: 20)
    }
}

let user = User(name: "민준")

  • convenience 키워드로 간단한 초기화 방식 제공





✏️ 클래스 고급 실습 과제

  • 상속과 다형성을 활용한 알림 시스템

    • 부모 클래스: Notification

    • 자식 클래스: EmailNotification, SMSNotification

    • 배열로 다양한 알림 객체 관리



  • ARC와 weak 참조를 활용한 친구 관계 관리
    • Person 클래스와 Friend 클래스 설계

    • 순환 참조 방지 구현





  • 타입 메서드로 인스턴스 수 카운팅

    • 모든 인스턴스 생성 시 카운트 증가 & 출력





  • [답] 상속과 다형성을 활용한 알림 시스템 



class Notification {
    func send() {
        print("📢 일반 알림 전송")
    }
}

class EmailNotification: Notification {
    override func send() {
        print("📧 이메일 알림 전송")
    }
}

class SMSNotification: Notification {
    override func send() {
        print("📩 SMS 알림 전송")
    }
}

// 다형성 활용: Notification 배열로 다양한 타입 관리
let notifications: [Notification] = [
    EmailNotification(),
    SMSNotification(),
    Notification()
]

for notification in notifications {
    notification.send()
}

/*
출력 결과:
📧 이메일 알림 전송
📩 SMS 알림 전송
📢 일반 알림 전송
*/


[답] 상속과 다형성을 활용한 알림 시스템
[답] 상속과 다형성을 활용한 알림 시스템 





  • [답]ARC와 weak 참조를 활용한 친구 관계 관리


class Person {
    let name: String
    // weak 키워드를 통해 순환 참조 방지
    weak var bestFriend: Friend?

    init(name: String) {
        self.name = name
        print("🧍‍♂️ Person \(name) 생성됨")
    }

    deinit {
        print("🧍‍♂️ Person \(name) 메모리 해제됨")
    }
}

class Friend {
    let nickname: String
    var owner: Person?

    init(nickname: String) {
        self.nickname = nickname
        print("👬 Friend \(nickname) 생성됨")
    }

    deinit {
        print("👬 Friend \(nickname) 메모리 해제됨")
    }
}

// 테스트
do {
    let person = Person(name: "지우")
    let friend = Friend(nickname: "민준")

    person.bestFriend = friend
    friend.owner = person
}
// do 블록이 끝나면 두 객체 모두 메모리 해제됨



[답]ARC와 weak 참조를 활용한 친구 관계 관리
[답]ARC와 weak 참조를 활용한 친구 관계 관리





  • [답]타입 메서드로 인스턴스 수 카운팅

class CounterObject {
    static var totalCount: Int = 0  // 타입 저장 프로퍼티

    init() {
        CounterObject.totalCount += 1
    }

    static func showTotalCount() {
        print("📦 현재까지 생성된 인스턴스 수: \(totalCount)")
    }
}

// 테스트
let obj1 = CounterObject()
let obj2 = CounterObject()
let obj3 = CounterObject()

CounterObject.showTotalCount()  // 📦 현재까지 생성된 인스턴스 수: 3



[답]타입 메서드로 인스턴스 수 카운팅
[답]타입 메서드로 인스턴스 수 카운팅




🎯 마무리하며


Swift 클래스 고급 기능 요약!

  • 상속다형성으로 확장성 높은 설계

  • ARC 이해로 메모리 누수 방지

  • 타입 프로퍼티/메서드로 클래스 단위 관리

  • Extension 으로 유지보수성 강화

  • final 키워드로 안정적인 클래스 보호


Swift에서 클래스를 제대로 활용하면

복잡한 앱 구조도 깔끔하게 설계할 수 있습니다.

댓글 쓰기