서버 개발자를 위한 Swift protocol 가이드 – Java/Kotlin interface와 비교하며 이해하기

서버 사이드에서 Java 또는 Kotlin으로 개발을 해오셨다면, interface라는 개념은 너무나 익숙할 겁니다. Swift에도 이와 유사한 개념으로 protocol이 존재합니다. 하지만 단순히 “Swift에서 interface는 protocol이다”라고만 이해하면 놓치는 부분이 많습니다.

Swift의 protocol은 interface + default method + 제네릭 + 확장성이 한데 어우러진, 꽤 강력한 개념입니다. 이번 글에서는 Java/Kotlin 인터페이스와 비교하면서 Swift의 프로토콜을 정리해보겠습니다.

🧩 1. 기본 개념: protocol ≒ interface

Swift의 protocol은 특정 타입이 가져야 할 **속성(Property)**와 **메서드(Method)**의 청사진(Contract)을 정의합니다. 기본적인 역할은 Java/Kotlin의 interface와 거의 동일합니다.

protocol Vehicle {
    var speed: Double { get set }   // 프로퍼티 요구사항
    func move()                     // 메서드 요구사항
}

struct Car: Vehicle {
    var speed: Double = 0.0

    func move() {
        print("Car is moving at \(speed) km/h")
    }
}


👉 Java/Kotlin에서 interface를 implements 하는 것과 거의 같습니다.

2. Java/Kotlin interface vs Swift protocol 요약 비교

항목Java/Kotlin interfaceSwift protocol
프로퍼티 정의메서드만 가능 (Kotlin은 val/var 가능)저장/계산 프로퍼티 모두 정의 가능 (get/set)
구조체/열거형 적용클래스만 구현 가능클래스, 구조체(struct), 열거형(enum) 모두 채택 가능
확장(기본 구현)default method (Java8+)protocol extension 으로 기본 구현 가능
다중 채택가능가능
제네릭제네릭 타입으로 선언associatedtype으로 제네릭 추상화 지원
Optional 요구사항없음 (모든 메서드 구현 필요)@objc optional 지원 (단, class 한정)
런타임 타입 캐스팅instanceof 등is, as?, as! 사용

 3. 클래스뿐 아니라 struct, enum도 채택 가능


Java/Kotlin 인터페이스는 클래스만 구현할 수 있지만, Swift에서는 **값 타입(Value Type)**인 구조체(struct), 열거형(enum)도 프로토콜을 채택할 수 있습니다.

enum Direction: Moveable {
    case north, south, east, west

    func move() {
        print("Moving \(self)")
    }
}

protocol Moveable {
    func move()
}


👉 Swift는 값 타입이 언어의 핵심 개념이라, 이런 패턴이 매우 흔합니다.

4. protocol extension으로 기본 구현 제공

Java 8 이후 interface에 default method를 정의할 수 있듯이, Swift도 protocol extension으로 기본 구현을 제공합니다.

하지만 Swift는 훨씬 강력합니다 — 프로토콜을 채택한 모든 타입에 공통 기능을 추가할 수 있죠.

protocol Logger {
    func log(_ message: String)
}

extension Logger {
    func log(_ message: String) {
        print("[LOG] \(message)")
    }
}

struct FileLogger: Logger {}
struct ConsoleLogger: Logger {}

FileLogger().log("Hello")    // 기본 구현 사용


👉 Kotlin의 interface default 구현과 비슷하지만, Swift에서는 extension으로 공통 동작을 부여하는 경우가 많습니다.

5. associatedtype으로 제네릭 추상화


Java/Kotlin에서는 인터페이스에 제네릭 타입을 붙여 추상화합니다.

interface Repository<T> {
    fun save(entity: T)
}


Swift에서는 associatedtype을 사용합니다.

protocol Repository {
    associatedtype Entity
    func save(_ entity: Entity)
}

struct UserRepository: Repository {
    func save(_ entity: User) {
        // 구현
    }
}


👉 associatedtype은 Swift의 제네릭 추상화 방식으로, Swift의 Protocol with Associated Types(PAT)는 굉장히 자주 등장하는 개념입니다.

6. @objc optional — 선택적 요구사항

Swift 프로토콜은 모든 요구사항이 기본적으로 필수입니다.

선택적 메서드를 정의하려면 Objective-C 호환 프로토콜(@objc)을 사용해야 합니다.

@objc protocol Delegate {
    @objc optional func didFinish()
}


하지만 네이티브 Swift에서는 보통 optional 대신 extension으로 기본 구현을 제공하는 방식이 일반적입니다.

7. 실무 예시

✅ Delegate 패턴

UIKit에서 흔히 쓰는 방식입니다.

protocol TableViewDelegate {
    func didSelectRow(at index: Int)
}



✅ Repository / UseCase 추상화


서버 API 인터페이스 정의 시

protocol UserRepository {
    func fetchUser(id: String) async throws -> User
}



✅ SwiftUI ViewModel 추상화

protocol ViewModel: ObservableObject {
    associatedtype State
    var state: State { get }
}

✨ 마무리: Swift는 “상속”보다 “프로토콜 조합”을 선호한다

Swift는 전통적인 클래스 상속보다는, 여러 개의 protocol을 조합해서 기능을 구성하는 방식을 선호합니다.

서버 개발자가 인터페이스를 “클래스 계약” 정도로만 사용했다면, Swift에선 프로토콜이 추상화의 주력 수단이 됩니다.

📌 한 줄 요약

Swift의 protocol = interface + default method + struct/enum 지원 + 제네릭 추상화 + 확장 기능

단순한 인터페이스 개념 이상으로, 언어 전체를 관통하는 핵심 요소입니다.


위로 스크롤