xxo' TIL/WIL

IOS/Swift

[Swift] 프로토콜(Protocol), 확장(Extension)

xxoxec 2025. 6. 22. 23:41
swift에서 프로토콜(protocol)은 특정한 기능을 제공하는 규약을 정의하는 역할을 합니다.
특정 작업이나 기능에 적합한 메서드, 프로퍼티 및 기타 요구사항의 '약속'을 정의하며, 즉 프로토콜은 해당 프로토콜을 채택하는 클래스, 구조체, 열거형 등이 어떤 메서드나 속성을 구현해야 하는지를 명시합니다.
프로토콜의 요구사항을 충족시키는 모든 타입은 해당 프로토콜을 준수한다 혹은 따른다(protocol conforming)고 합니다. 프로토콜을 사용하면 코드의 재사용성, 확장성, 유연성을 높일 수 있습니다.

 

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/protocols/

 

Documentation

 

docs.swift.org

 

프로토콜(Protocol) : 프로토콜은 특정 작업이나 기능에 필요한 메서드, 프로퍼티 및 기타 요구 사항의 청사진을 정의한다.

프로토콜은 어떤 약속(역할)을 정해 놓은 것인데, 여기서 약속이란 메서드, 프로퍼티를 뜻한다.

구조체, 클래스, 열거형은 프로토콜을 채택하여 해당 프로토콜의 요구 사항을 실제로 구현할 수 있다.

즉 프로토콜은 제공하고 싶은 역할(기능, 속성)을 미리 정의해 놓은 것인데 이후에 다른 타입이 해당 프로토콜의 역할을 제공하고 싶으면, conform 해서 제공한다. protocol 키워드를 앞에 붙이고, 프로토콜의 이름을 작성한다.

protocol SomeProtocol {
 // 프로토콜 내용
 }
 
 protocol MyProtocol {
    var property: String { get set }
    func doSomething()
}

 

프로토콜 채택

  • 클래스, 구조체, 열거형에서 정의한 프로토콜을 채택하기 위해서는 콜론(:)을 사용한다.
  • 하나의 타입에서 다수의 프로토콜을 채택하기 위해서는 콤마(,)를 사용한다.
  • 클래스에서 상속과 프로토콜 채택을 동시에 하려면 상속받으려는 클래스를 먼저 명시하고, 그 뒤에 채택할 프로토콜 목록을 작성한다.
protocol SomeProtocol {
}
// 프로토콜 채택
struct SomeStructure: SomeProtocl {
}
// 다수의 프로토콜 채택
struct SomeStructure: SomeProtocol, AnotherProtocol {
}

class MyClass: MyProtocol {
    var property: String = "Hello"
    
    func doSomething() {
        print("Something done!")
    }
}

 

예 1:) 프로토콜을 일상에서의 예를 들면, 자동차 제조 시 일정한 표준 또는 규약, 즉 프로토콜을 지켜야 한다. 모든 자동차는 바퀴와 창문이 있어야 하며, 브레이크와 창문 열기 기능도 포함되어야 한다.

자동차 제조시를 예로 프로토콜 표현한 예

CarProtocol 프로토콜은 자동차가 가져야 할 기본적인 특성과 기능을 정의한다. Sedan 클래스는 CarProtocol 을 채택하여 해당 프로토콜의 요구 사항을 구체적으로 구현한다. 이렇게 protocol 을 사용하면 특정 규약 또는 표준을 명확하게 정의하고, 이를 채택하는 타입이 해당 규약을 준수하도록 보장할 수 있다.

 

예 2:) 또 다른 일상에서의 예로 학급 반장이라는 프로토콜이 있다면 이 속성에는 이름, 해당 학급반 등이 있을 수 있고, 할 일에는 대표로 인사하기, 소풍시 인원 점검하기 등이 있다.

어떤 약속(역할)을 정해 놓은 것이지 아직 구현된 것은 아니므로 따라서 개발 시 어떤 객체가 해당 역할을 수행할지 정하고 그다음에 해당 객체가 그 역할을 어떻게 구현할지 정하면 된다. 이것을 protocol conforming 이라고 한다.

protocol conforming

 

예 3:)축구를 예를 들면 코치는 코치의 역할이 있다. 코치의 속성으로는 name, currentTeam이 있고 역할에는 training, direct가 있다.

프로토콜을 축구로 예

 

프로토콜(Protocol)이 필요한 이유

개발을 하다 보면 다양한 객체를 만들게 된다. 다양한 객체 간에 공통 역할을 발견하게 되고 해당 역할을 한정된 객체에서만 쓰지 않고, 여러 객체로 확장이 필요할 때가 있다. 이럴 때 그 역할을 프로토콜로 정의하고 해당 역할이 필요한 객체가 나올 때마다 해당 프로토콜을 채택해서 역할을 줄 수 있다.

  • 한 가지 객체에 대해서만 buy() 메서드를 정의할 때

한가지 객체에 대해서만 buy() 메서드를 정의할 때

  • Purchaseable 역할에 buy() 메서드를 정의할 때

Purchaseable  역할에 buy() 메소드를 정의할때

 

프로토콜 상속(protocol inheritance) :  프로토콜은 다른 프로토콜을 상속받을 수 있다. 프로토콜 상속 문법은 클래스의 상속 문법과 유사하지만 클래스와 다르게 하나 이상의 여러 개의 다중상속이 가능하며, 다중상속이 되다 보니, 프로토콜을 더 작고 명확하게 나눌 수 있다. 이를 통해 프로토콜이 더 구체적인 요구사항을 정의할 수고, 재사용성이 늘고 테스트 가능성도 더 높아진다.

protocol AnotherProtocol: MyProtocol {
    func anotherMethod()
}

하나 이상의 여러 개의 다중상속이 가능, 더 구체적인 요구사항을 정의할 수고, 재사용성이 늘고 테스트 가능성도 더 높아진다.

 

프로토콜의 프로퍼티, 메서드 요구 사항

프로퍼티 : 프로퍼티는 타입과 이름만 작성한다. gettable/settable 여부를 작성하며 프로퍼티는 var 로 선언해야 한다

메서드 : 메서드는 함수명과 반환 값을 지정할 수 있고, 메서드 내용을 작성하지 않아도 된다.

변경 가능한 메서드 요구사항 (mutating 키워드) : mutating 키워드를 사용하면, 값 타입 형에서 채택한 프로콜에서는 변경가능하다.

 

확장(Extension) : 기존에 있던 타입에 새로운 역할(기능 및 속성)을 추가하고 싶을 때 기능을 추가할 수 있게 해 준다.

새로운 역할(기능 및 속성)을 추가하고 싶을 때
기존의 String 타입에 특정 기능을 추가하고 싶을 때 사용해 볼 수 있다.

 

Protocol Extension

  • protocol 은 어떤 역할에 대한 정의를 설명해 준다. 다만 실제 구현은 제공하지 않는다.
  • extension 은 기능에 대한 구현까지 제공한다. 다만 한 가지 타입에만 적용된다.
  • protocol extension 은 위에 있는 두 가지 단점을 보완해 줄 수 있다. protocol 에 기본 구현을 제공해 줄 수 있고 protocol을 채택하는 여러 타입에 기능을 제공해 줄 수 있다.
protocol SomeProtocol {
 func method()
}
extension SomeProtocol {
 func method() {
 // 기본 구현
 }
}
class SomeClass: SomeProtocol {
 // method 함수를 정의하지 않아도 에러가 발생하지 않는다.
}

protocol 에 기본 구현을 제공해 줄 수 있고 protocol을 채택하는 여러 타입에 기능을 제공해줄 수 있다.

 

Protocol Oriented Programming : 3가지 덕분에 POP(protocol oriented programming)이 가능하다.

  • protocol 은 어떤 역할에 대한 정의를 제공
  • extension 은 어떤 타입에 구현을 제공
  • protocol extension 은 어떤 역할에 대한 기본 구현 제공

Protocol Oriented Programming

 

 

 


 

 

프로토콜의 사용 예시

  • 프로토콜을 통한 다형성 : 여러 종류의 객체가 동일한 메서드를 구현하게 만들어, 타입에 관계없이 메서드를 호출할 수 있게 한다.
  • 델리게이션 패턴 : 델리게이션 패턴에서 사용되는 프로토콜은 이벤트나 작업을 다른 객체에 위임하는 데 유용하다.
    • 델리게이트(Delegate) 패턴 : 델리게이트 패션은 디자인 패턴 중 하나로, 프로그램 안에서 어떤 객체를 대신해서 행동한다던지 다른 객체와 협동해서 일할 수 있게끔 권한을 위임하는 패턴이다.
    • iOS에서는 UITableViewDelegate나 UICollectionViewDelegate를 예시로 들 수 있다.
    • Delegate 패턴을 사용하는 이유
      • 델리게이트 패턴은 한 클래스와 다른 클래스의 상호작용을 간단히 할 수 있도록 돕는다.
      • 델리게이트 패턴은 1:1 관계에서 매우 유용하다.
      • 델리게이트는 프로토콜을 준수하는 것만으로 구현이 가능하므로 매우 유연하다.
  • 제네릭과 프로토콜 : 제네릭과 결합하여 더 유연하고 확장 가능한 코드 작성이 가능하다.

프로토콜은 객체 지향 프로그래밍(OOP)에서 중요한 역할을 하며, swift의 강력한 타입 시스템을 활요하는 데 필수적인 요소이다.