Swift Protocol and Extensions

프로토콜의 정의와 채택 (Defining and Adopting Protocols)

프로토콜 정의 (Defining a Protocol)

프로토콜은 특정 요구사항을 정의하는 청사진입니다. 클래스, 구조체, 열거형이 프로토콜을 채택하여 이 요구사항을 구현할 수 있습니다. 프로토콜은 protocol 키워드를 사용하여 정의합니다.

protocol Greetable {
    var greeting: String { get }
    func greet()
}

프로토콜 채택 (Adopting a Protocol)

클래스, 구조체, 열거형이 프로토콜을 채택하려면 프로토콜이 정의한 요구사항을 구현해야 합니다.

class Person: Greetable {
    var name: String

    var greeting: String {
        return "Hello, \(name)!"
    }

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

    func greet() {
        print(greeting)
    }
}

let person = Person(name: "Alice")
person.greet()  // "Hello, Alice!"

프로토콜 상속 (Protocol Inheritance)

프로토콜은 다른 프로토콜을 상속하여 새로운 프로토콜을 정의할 수 있습니다.

protocol Named {
    var name: String { get }
}

protocol Aged {
    var age: Int { get }
}

protocol PersonProtocol: Named, Aged {
    func introduce()
}

struct Student: PersonProtocol {
    var name: String
    var age: Int

    func introduce() {
        print("My name is \(name) and I am \(age) years old.")
    }
}

let student = Student(name: "John", age: 20)
student.introduce()  // "My name is John and I am 20 years old."

프로토콜 컴포지션 (Protocol Composition)

여러 프로토콜을 조합하여 하나의 타입으로 사용할 수 있습니다.

protocol Drivable {
    func drive()
}

protocol Flyable {
    func fly()
}

struct FlyingCar: Drivable, Flyable {
    func drive() {
        print("Driving")
    }

    func fly() {
        print("Flying")
    }
}

let vehicle: Drivable & Flyable = FlyingCar()
vehicle.drive()  // "Driving"
vehicle.fly()    // "Flying"

프로토콜 확장 (Protocol Extensions)

프로토콜 확장을 통해 기본 구현을 제공할 수 있습니다.

protocol Describable {
    func describe()
}

extension Describable {
    func describe() {
        print("This is a describable item.")
    }
}

struct Book: Describable {}

let book = Book()
book.describe()  // "This is a describable item."

익스텐션의 활용 (Using Extensions)

익스텐션 정의 (Defining Extensions)

익스텐션을 사용하여 기존 클래스, 구조체, 열거형, 프로토콜에 새로운 기능을 추가할 수 있습니다. extension 키워드를 사용하여 정의합니다.

extension Int {
    func squared() -> Int {
        return self * self
    }
}

let number = 5
print(number.squared())  // 25

익스텐션을 통한 계산 속성 추가 (Adding Computed Properties with Extensions)

익스텐션을 사용하여 계산 속성을 추가할 수 있습니다.

extension Double {
    var km: Double { return self * 1_000.0 }
    var m: Double { return self }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1_000.0 }
}

let distance = 42.0
print("\(distance.km) km")  // "42000.0 km"
print("\(distance.m) m")    // "42.0 m"
print("\(distance.cm) cm")  // "0.42 cm"
print("\(distance.mm) mm")  // "0.042 mm"

익스텐션을 통한 메서드 추가 (Adding Methods with Extensions)

익스텐션을 사용하여 새로운 메서드를 추가할 수 있습니다.

extension String {
    func reversedString() -> String {
        return String(self.reversed())
    }
}

let message = "Hello"
print(message.reversedString())  // "olleH"

익스텐션을 통한 초기화 메서드 추가 (Adding Initializers with Extensions)

익스텐션을 사용하여 초기화 메서드를 추가할 수 있습니다.

struct Point {
    var x = 0.0
    var y = 0.0
}

extension Point {
    init(value: Double) {
        self.x = value
        self.y = value
    }
}

let point = Point(value: 3.0)
print("x: \(point.x), y: \(point.y)")  // "x: 3.0, y: 3.0"

프로토콜 준수와 익스텐션 (Protocol Conformance with Extensions)

익스텐션을 사용하여 기존 타입을 프로토콜에 적합하도록 만들 수 있습니다.

protocol Identifiable {
    var id: String { get }
}

struct User {
    var name: String
}

extension User: Identifiable {
    var id: String {
        return name
    }
}

let user = User(name: "Alice")
print(user.id)  // "Alice"

이와 같이 Swift에서 프로토콜과 익스텐션은 강력한 기능을 제공합니다. 프로토콜을 정의하고 채택하는 방법, 그리고 익스텐션을 활용하여 기존 타입에 새로운 기능을 추가하는 방법에 대해 상세하게 설명하고 다양한 예제를 제공했습니다. 추가적인 질문이나 더 많은 예제가 필요하면 언제든지 알려주세요!

Leave a Reply

Your email address will not be published. Required fields are marked *