IMCAT.DEV
로그인 가입
Swift 중급 객체지향

Swift 객체지향 프로그래밍(OOP) 심화

Swift 객체지향 프로그래밍(OOP) 심화 — 중급

객체지향 프로그래밍(OOP) 심화

1. 도입 (왜 배워야 하는가)

객체지향 프로그래밍(OOP)은 소프트웨어 개발에서 매우 중요한 패러다임입니다. OOP를 활용하면 코드의 재사용성과 유지보수성을 높일 수 있으며, 복잡한 시스템을 보다 쉽게 이해하고 관리할 수 있습니다. 만약 OOP의 개념을 제대로 이해하지 못한다면, 코드가 점점 복잡해지고 비효율적으로 변할 수 있으며, 팀원 간의 협업에도 어려움이 생길 수 있습니다. 특히 대규모 프로젝트에서는 OOP의 장점을 제대로 활용하지 못할 경우, 버그 발생 확률이 높아지고, 개발 속도가 저하될 수 있습니다.

2. 핵심 개념 설명

2-1. 클래스와 객체

클래스(Class)는 객체를 생성하기 위한 청사진입니다. 객체(Object)는 클래스의 인스턴스이며, 특정한 상태와 행동을 가집니다. 예를 들어, "자동차"라는 클래스를 만들면, "내 차"는 그 클래스의 객체가 됩니다. 내 차는 색상, 모델, 속도 등의 상태를 가지며, "주행하다", "멈추다"와 같은 행동을 가질 수 있습니다.

용어설명
클래스객체의 속성과 행동을 정의한 틀
객체클래스로부터 생성된 실체
인스턴스클래스를 통해 만들어진 구체적인 객체

2-2. 상속

상속은 새로운 클래스가 기존 클래스의 속성과 메소드를 물려받는 기능입니다. 이는 코드의 재사용성을 높여주며, 기본 클래스와 파생 클래스 간의 관계를 정의합니다. 예를 들어, "동물"이라는 클래스를 만들고, "개"와 "고양이"라는 클래스를 만들면, 이 두 클래스는 동물 클래스를 상속받을 수 있습니다.

2-3. 다형성

다형성은 동일한 메소드가 다양한 형태로 동작할 수 있는 능력입니다. 예를 들어, "소리내다"라는 메소드를 동물 클래스에서 정의하고, 개와 고양이 클래스에서 각각 다른 방식으로 구현할 수 있습니다.

3. 기본 코드 예제

아래는 간단한 클래스를 정의하고 객체를 생성하는 코드입니다.

class Animal {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func makeSound() {
        print("이 동물의 소리입니다.")
    }
}

let dog = Animal(name: "멍멍이")
dog.makeSound()

실행 결과: 이 동물의 소리입니다.

  • class Animal: Animal이라는 클래스를 정의합니다.
  • var name: String: Animal 객체의 name 속성을 정의합니다.
  • init(name: String): 객체를 초기화하는 초기화 메소드를 정의합니다.
  • func makeSound(): 동물이 소리를 내는 메소드를 정의합니다.
  • let dog = Animal(name: "멍멍이"): Animal 클래스의 인스턴스인 dog를 생성합니다.
  • dog.makeSound(): dog 객체의 makeSound() 메소드를 호출하여 소리를 출력합니다.
  • 4. 실전 활용 예제

    4-1. 쇼핑몰에서 장바구니 구현

    장바구니를 클래스로 구현할 수 있습니다.

    class Cart {
        var items: [String] = []
        
        func addItem(item: String) {
            items.append(item)
            print("\(item)을(를) 장바구니에 추가했습니다.")
        }
        
        func showItems() {
            print("장바구니에 있는 아이템: \(items.joined(separator: ", "))")
        }
    }
    
    let myCart = Cart()
    myCart.addItem(item: "사과")
    myCart.addItem(item: "바나나")
    myCart.showItems()

    실행 결과:

    사과을(를) 장바구니에 추가했습니다.
    바나나을(를) 장바구니에 추가했습니다.
    장바구니에 있는 아이템: 사과, 바나나
  • class Cart: 장바구니 클래스를 정의합니다.
  • var items: [String]: 장바구니에 담긴 아이템을 배열로 저장합니다.
  • func addItem(item: String): 아이템을 추가하는 메소드를 정의합니다.
  • func showItems(): 장바구니의 아이템을 출력하는 메소드를 정의합니다.
  • 4-2. 다형성을 활용한 동물 소리 출력

    다양한 동물 클래스를 정의하고 다형성을 활용해 소리를 출력할 수 있습니다.

    class Dog: Animal {
        override func makeSound() {
            print("멍멍!")
        }
    }
    
    class Cat: Animal {
        override func makeSound() {
            print("야옹!")
        }
    }
    
    let animals: [Animal] = [Dog(name: "강아지"), Cat(name: "고양이")]
    
    for animal in animals {
        animal.makeSound()
    }

    실행 결과:

    멍멍!
    야옹!
  • class Dog와 class Cat: Animal 클래스를 상속받아 각각의 소리를 구현합니다.
  • let animals: [Animal]: 다양한 동물 객체를 배열로 저장합니다.
  • for animal in animals: 각 동물 객체에 대해 makeSound() 메소드를 호출하여 소리를 출력합니다.
  • 5. 흔한 실수와 주의사항

    5-1. 초기화 메소드 누락

    잘못된 코드:

    class Animal {
        var name: String
    }
    
    let dog = Animal() // 초기화 메소드가 없어서 에러 발생

    올바른 코드:

    class Animal {
        var name: String
        
        init(name: String) {
            self.name = name
        }
    }
    
    let dog = Animal(name: "멍멍이")

    5-2. 상속 시 메소드 오버라이딩 누락

    잘못된 코드:

    class Dog: Animal {
        func makeSound() { // 'override' 키워드가 없음
            print("멍멍!")
        }
    }

    올바른 코드:

    class Dog: Animal {
        override func makeSound() {
            print("멍멍!")
        }
    }

    6. 정리

  • OOP는 소프트웨어의 재사용성과 유지보수성을 높이는 데 필수적입니다.
  • 클래스는 객체의 속성과 행동을 정의하며, 객체는 클래스의 인스턴스입니다.
  • 상속과 다형성을 활용하여 코드의 재사용성을 향상시킬 수 있습니다.
  • 다음에 학습하면 좋은 주제: 프로토콜(Protocol)과 제네릭(Generics) 사용법, 디자인 패턴(예: Singleton, Factory) 등.