🔥 프로토콜의 메서드 요구사항

382자
5분

프로토콜은 특정 인스턴스 메서드나 타입 메서드를 준수하는 타입에서 구현하도록 요구할 수 있습니다. 이러한 메서드들은 일반적인 인스턴스 메서드 및 타입 메서드와 정확히 동일한 방식으로 프로토콜의 정의에 작성되지만, 중괄호({})나 메서드 본문은 포함하지 않죠. 변위(variadic) 매개변수도 일반 메서드와 동일한 규칙에 따라 허용됩니다. 하지만 프로토콜의 정의 내에서는 메서드 매개변수에 대한 기본값을 지정할 수 없답니다.

타입 속성 요구사항과 마찬가지로, 프로토콜에서 타입 메서드 요구사항을 정의할 때는 항상 static 키워드를 앞에 붙여야 합니다. 클래스에서 타입 메서드 요구사항을 구현할 때 classstatic 키워드를 앞에 붙이더라도, 프로토콜에서는 항상 static을 사용하는 것이 원칙이에요.

protocol SomeProtocol {
    static func someTypeMethod() // 타입 메서드 요구사항
}
swift

다음 예제는 단일 인스턴스 메서드 요구사항을 가진 프로토콜을 정의합니다.

protocol RandomNumberGenerator {
    func random() -> Double // Double 값을 반환하는 인스턴스 메서드 요구사항
}
swift

RandomNumberGenerator 프로토콜은 준수하는 모든 타입이 random이라는 인스턴스 메서드를 가지도록 요구합니다. 이 메서드는 호출될 때마다 Double 값을 반환해야 하죠. 프로토콜의 일부로 명시되진 않았지만, 이 값은 0.0부터 1.0 미만까지의 숫자일 것으로 가정됩니다.

RandomNumberGenerator 프로토콜은 각 난수가 어떻게 생성될지에 대해서는 어떠한 가정도 하지 않습니다. 단순히 생성기가 새로운 난수를 생성하기 위한 표준 방법을 제공하도록 요구할 뿐이에요.

아래는 RandomNumberGenerator 프로토콜을 채택하고 준수하는 클래스의 구현 예시입니다. 이 클래스는 선형 합동 생성기(linear congruential generator)라고 알려진 의사 난수 생성 알고리즘을 구현하고 있죠.

class LinearCongruentialGenerator: RandomNumberGenerator {
    var lastRandom = 42.0 // 마지막으로 생성된 난수 값
    let m = 139968.0 // 모듈로 연산에 사용되는 값
    let a = 3877.0 // 곱셈에 사용되는 값
    let c = 29573.0 // 덧셈에 사용되는 값
 
    func random() -> Double {
        lastRandom = ((lastRandom * a + c)
            .truncatingRemainder(dividingBy:m)) // 선형 합동 식을 계산
        return lastRandom / m // 새로운 난수 값을 반환
    }
}
 
let generator = LinearCongruentialGenerator()
print("Here's a random number: \(generator.random())")
// "Here's a random number: 0.3746499199817101" 등의 난수 출력
print("And another one: \(generator.random())")
// "And another one: 0.729023776863283" 등의 난수 출력
swift

LinearCongruentialGenerator 클래스는 RandomNumberGenerator 프로토콜을 채택하고, 프로토콜에서 요구하는 random() 메서드를 구현합니다. 이 메서드는 선형 합동 식을 사용하여 새로운 난수 값을 생성하죠.

프로토콜의 메서드 요구사항은 프로토콜을 준수하는 타입이 반드시 구현해야 할 메서드의 청사진을 제공합니다. 이를 통해 프로토콜은 준수하는 타입의 인터페이스를 정의하고, 해당 타입이 특정 동작을 수행하도록 보장할 수 있습니다.

lecture image

프로토콜의 메서드 요구사항을 잘 활용하면 타입의 동작을 추상화하고, 코드의 유연성과 재사용성을 크게 향상시킬 수 있습니다. 프로토콜을 통해 인터페이스를 정의하고, 다양한 타입에서 해당 인터페이스를 구현하는 방식으로 코드를 설계해 보세요. 더욱 간결하고 확장 가능한 코드를 작성할 수 있을 거예요!