J
[Swift] Protocol 본문
1. Protocol이란?
Protocol(프로토콜)은 특정 작업이나 기능에 대한 요구 사항의 집합을 정의하는 데 사용.
프로토콜은 클래스, 구조체, 열거형 등에서 구현할 수 있으며, 객체 지향 프로그래밍의 인터페이스와 유사한 역할.
2. Protocol의 주요 특징
- 구현 강제화
- 프로토콜을 채택한 타입은 프로토콜에서 정의한 요구 사항을 반드시 구현해야 함.
- 유연한 설계
- 클래스, 구조체, 열거형 모두 프로토콜을 채택할 수 있음.
- 다중 채택 가능
- 하나의 타입이 여러 프로토콜을 채택할 수 있음.
- 타입 독립성
- 프로토콜을 통해 타입 간 의존성을 줄이고, 코드 재사용성을 높일 수 있음.
3. Protocol의 기본 문법
protocol ProtocolName {
// 요구 사항 정의
}
4. Protocol의 사용 예제
protocol Greetable {
func greet()
}
struct Person: Greetable {
func greet() {
print("Hello!")
}
}
let person = Person()
person.greet() // "Hello!"
5. 프로토콜의 구성 요소
메서드 요구 사항
프로토콜은 메서드의 선언만 정의하며, 구현은 없음.
protocol Drawable {
func draw()
}
struct Circle: Drawable {
func draw() {
print("Drawing a circle")
}
}
프로퍼티 요구 사항
프로토콜은 프로퍼티의 이름, 타입, 읽기/쓰기 권한만 정의.
protocol Shape {
var area: Double { get }
var perimeter: Double { get set }
}
struct Rectangle: Shape {
var width: Double
var height: Double
var area: Double {
return width * height
}
var perimeter: Double {
get {
return 2 * (width + height)
}
set {
width = newValue / 4
height = newValue / 4
}
}
}
초기화 요구 사항
프로토콜은 초기화 메서드도 요구할 수 있음.
protocol Initializable {
init(value: Int)
}
struct MyStruct: Initializable {
var value: Int
init(value: Int) {
self.value = value
}
}
let myStruct = MyStruct(value: 10)
6. Protocol과 Extension
Swift에서는 프로토콜 확장을 통해 기본 구현을 제공할 수 있음.
이를 사용하면 프로토콜을 채택하는 타입에서 선택적으로 구현을 제공할 수 있음.
protocol Playable {
func play()
}
extension Playable {
func play() {
print("Default playing...")
}
}
struct Game: Playable {}
let game = Game()
game.play() // "Default playing..."
7. Protocol Composition (프로토콜 조합)
하나의 타입이 여러 프로토콜을 동시에 준수해야 할 때, & 연산자를 사용하여 프로토콜 조합을 정의할 수 있음.
protocol Flyable {
func fly()
}
protocol Swimmable {
func swim()
}
struct Duck: Flyable, Swimmable {
func fly() {
print("Flying...")
}
func swim() {
print("Swimming...")
}
}
func performActions(animal: Flyable & Swimmable) {
animal.fly()
animal.swim()
}
let duck = Duck()
performActions(animal: duck)
8. Protocol의 활용
타입 간 통합된 인터페이스 제공
프로토콜은 타입 간 공통된 인터페이스를 제공하여 다형성을 구현 가능.
protocol Animal {
func sound() -> String
}
struct Dog: Animal {
func sound() -> String {
return "Woof"
}
}
struct Cat: Animal {
func sound() -> String {
return "Meow"
}
}
let animals: [Animal] = [Dog(), Cat()]
for animal in animals {
print(animal.sound())
}
Delegate 패턴
Delegate 패턴에서 프로토콜은 객체 간 통신을 정의하는 데 사용.
protocol TaskDelegate: AnyObject {
func taskDidComplete()
}
class Task {
weak var delegate: TaskDelegate?
func performTask() {
print("Task performed")
delegate?.taskDidComplete()
}
}
class Manager: TaskDelegate {
func taskDidComplete() {
print("Task completed successfully!")
}
}
let task = Task()
let manager = Manager()
task.delegate = manager
task.performTask()
// "Task performed"
// "Task completed successfully!"
9. Protocol과 Associatedtype
프로토콜에서 연관 타입(associatedtype)을 사용하면 제네릭 프로그래밍과 결합하여 더욱 유연한 코드를 작성할 수 있음.
protocol Container {
associatedtype Item
mutating func add(_ item: Item)
var count: Int { get }
}
struct Box<T>: Container {
typealias Item = T
private var items: [T] = []
mutating func add(_ item: T) {
items.append(item)
}
var count: Int {
return items.count
}
}
var box = Box<Int>()
box.add(5)
box.add(10)
print(box.count) // 2
10. Protocol의 실질적 사용 예
Codable
Swift의 Codable 프로토콜은 데이터를 인코딩하거나 디코딩하는 데 사용 됨.
struct User: Codable {
var name: String
var age: Int
}
let user = User(name: "Alice", age: 25)
if let data = try? JSONEncoder().encode(user) {
print(String(data: data, encoding: .utf8)!)
}
if let decoded = try? JSONDecoder().decode(User.self, from: data) {
print(decoded)
}
Equatable
Equatable은 객체 간의 동등성을 비교하기 위한 프로토콜.
struct Point: Equatable {
var x: Int
var y: Int
}
let p1 = Point(x: 1, y: 2)
let p2 = Point(x: 1, y: 2)
print(p1 == p2) // true
Protocol과 Class-Only 제한
프로토콜을 클래스에서만 채택하도록 제한하려면 AnyObject를 사용.
protocol ClassOnlyProtocol: AnyObject {
func doSomething()
}
class MyClass: ClassOnlyProtocol {
func doSomething() {
print("Doing something")
}
}
11. 결론
Swift의 Protocol은 코드 설계의 유연성을 높이고, 타입 독립적이고 재사용 가능한 코드를 작성하는 데 필수적인 도구.
프로토콜을 사용하면 타입 간의 공통 동작을 정의하고, 확장성과 유지보수성을 높일 수 있음.
특히, 제네릭 및 프로토콜 확장을 함께 활용하면 더욱 강력한 코드를 작성 가능.
'Swift' 카테고리의 다른 글
[Swift] self / Self (0) | 2024.04.18 |
---|---|
[Swift] associatedtype (0) | 2024.04.18 |
[Swift] Generic (0) | 2024.04.15 |
[Swift] GCD vs Swift Concurrency: 스레드 관리와 성능 (0) | 2024.04.15 |
[Swift] Swift Concurrency (0) | 2024.04.15 |