Swift에서 프로토콜(Protocol)은 특정 기능을 수행하기 위한 속성이나 메서드의 청사진(blueprint)을 정의하는 타입입니다.
클래스, 구조체, 열거형 등 다양한 타입이 프로토콜을 채택하여 해당 요구사항을 구현할 수 있습니다.
Swift는 객체 지향 언어이면서도 프로토콜 지향 프로그래밍(protocol-oriented programming)을 강력하게 지원합니다.
이는 Swift의 핵심적인 설계 철학 중 하나로, 프로토콜을 활용한 유연한 추상화와 확장이 가능합니다.
1. 프로토콜 기본 문법
protocol Greetable {
var name: String { get }
func greet()
}
위 예시는 name
이라는 읽기 가능한 프로퍼티와, greet()
라는 메서드를 요구합니다.
이 프로토콜을 채택한 타입은 해당 요구사항을 반드시 구현해야 합니다.
2. 프로토콜 채택과 구현
struct Person: Greetable {
var name: String
func greet() {
print("안녕하세요, 저는 \(name)입니다.")
}
}
let user = Person(name: "지민")
user.greet()
Person
구조체는 Greetable
프로토콜을 채택하고, 요구된 속성과 메서드를 구현하였습니다.
3. 클래스에서의 프로토콜 채택
class Dog: Greetable {
var name: String
init(name: String) {
self.name = name
}
func greet() {
print("\(name)가 꼬리를 흔듭니다.")
}
}
프로토콜은 상속이 아니라 채택(adopt)하는 방식이며, 여러 개의 프로토콜을 동시에 채택할 수도 있습니다.
4. 프로토콜 상속
protocol Named {
var name: String { get }
}
protocol Describable: Named {
var description: String { get }
}
Describable
은 Named
를 상속하므로, 이를 채택한 타입은 두 프로토콜의 모든 요구사항을 충족해야 합니다.
5. 프로토콜 확장 (Protocol Extension)
Swift의 가장 강력한 기능 중 하나는 프로토콜 확장입니다.
이를 통해 프로토콜 자체에 기본 구현을 제공할 수 있습니다.
extension Greetable {
func greet() {
print("안녕하세요, \(name)!")
}
}
해당 프로토콜을 채택한 타입이 직접 greet()
를 구현하지 않으면, 위에서 정의한 기본 구현이 사용됩니다.
6. 프로토콜을 활용한 다형성
let people: [Greetable] = [
Person(name: "은우"),
Dog(name: "바둑이")
]
for item in people {
item.greet()
}
Person
과 Dog
은 서로 다른 타입이지만, 모두 Greetable
을 따르기 때문에 배열에 담아 동일하게 처리할 수 있습니다.
마무리
Swift의 프로토콜은 코드의 재사용성과 유연성을 극대화할 수 있는 중요한 기능입니다.
특히 프로토콜 지향 프로그래밍을 통해 공통 기능을 추상화하고, 구조체나 열거형에서도 객체지향적인 설계를 할 수 있습니다.extension
과 함께 활용하면 클래스 상속보다도 더 강력한 설계가 가능하며, 실무에서도 널리 사용됩니다.