Protocol Basic
Swift를 잘 다루고 여러 샘플 코드들을 정확히 이해하려면 protocol
은 완벽히 익히고 있어야 한다고 생각합니다. 어떻게 보면 Swift의 강력한 기능 중 하나가 protocol
이라고 생각됩니다.
그럼 지금부터 protocol
에 대해서 천천히 알아가는 시간을 갖도록 하겠습니다.
애플의 공식문서에 정의된 protocol
의 정의는 다음과 같습니다.
"A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality."
직역하자면 다음과 같습니다.
"protocol은 특정 작업 혹은 기능들을 구현하기 위한 메소드, 프로퍼티 그리고 기타 다른 요구사항들의 청사진이다."
흡사 Java의 Interface와 비슷해보입니다.
하지만 어느 문서와 마찬가지로 정확하게 와닿는 설명이 아닐 수 있습니다. 조금 더 쉽게 풀어서 설명해보도록 하겠습니다.
Protocol
이란 무엇인가?
저는 다음과 같이 정의하고 싶습니다.
protocol
은 해당 이름에 걸맞는 기능을 하기 위해서 구현해야 하는 것들의 리스트입니다.
개발을 할 때 네이밍을 잘하는 것이 중요한 이유 중 하나가 해당 변수, 클래스, 구조체 그리고 Swift에서는 protocol
까지 그것들의 이름만 봐도 역할이 명확하게 나타나야하기 때문입니다.
여러분이 만역 “컴퓨터공학과 학부생” 이라는 타이틀을 갖고 그에 알맞는 능력을 갖고 싶다면 몇몇 과목들을 이수해야합니다. 그리고 기본적으로 갖춰야할 장비들도 존재합니다.
여기서 우리는 “컴퓨터공학과 학부생” 프로토콜을 설계해볼 수 있습니다.
컴공생이라면 노트북을 보유해야합니다. 하지만 노트북이 없고 집에 데스크탑으로 보유하고 있을 수도 있습니다. 또한 필수로 이수해야할 과목들이 존재합니다.
- 자료구조
- 운영체제
- 네트워크
또한 필수는 아니더라도 개인의 진로와 방향에 따라 부수적으로 수강할 수도 안 할 수도 있는 과목들도 존재합니다.
- 그래픽스
그럼 이러한 시나리오를 바탕으로 프로토콜을 작성해보도록 하겠습니다.
protocol ComputerScienceStudent{
var name:String { get }
var laptop:String? { get set }
func doDataStructure()
func doOperatingSystem()
func doNetwork()
}
기본적인 프로퍼티로 이름을 지칭하는 name
이 있을 수 있습니다. 또한 위에서 언급했던 것과 마찬가지로 노트북을 보유하고 있을수도 없을수도 있기 때문에 laptop
은 옵셔널 타입으로 지정하였습니다.
여기서 먼저 살펴보아야 할 것은 프로퍼티의 { get }
과 { get set }
입니다.
- 우선
{ get }
은 프로토콜을 따를 때 해당 변수는{ get }
과{ get set }
둘 중 하나만 구현해도 됩니다.
class Student:ComputerScienceStudent{
var _name:String = ""
var name:String{
get{
return self._name
}
set{
self._name = newValue
}
/*
method code
*/
}
}
주의해야할 것은 { set }
만 구현할 수는 없습니다.
- 다음은
{ get set }
입니다.{ get set }
은 프로토콜을 따를 때 해당 변수는 반드시{ get set }
을 모두 구현해야 한다는 것입니다. 위의{ get }
처럼 둘 중 하나만 구현하는 것이 아니라{ get set }
모두 구현을 해야합니다.
class Student:ComputerScienceStudent{
var _laptop:String?
var laptop:String?{
get{
return self._laptop
}
set{
self._laptop = newValue
}
}
/*
// Error : get과 set모두 구현해야 한다.
var laptop:String?{
get {
return self._laptop
}
}
*/
/*
method code
*/
}
또한 필수로 구현해야 하는 메소드들도 반드시 구현을 해야합니다.
class Student:ComputerScienceStudent{
/*
property code
*/
func doDataStructure(){
print("I love Data Structure")
}
func doOperatingSystem(){
print("It's boring")
}
func doNetwork(){
print("I like Network")
}
}
일반적으로 선언된 메소드들은 하나라도 구현하지 않으면 에러를 발생시킵니다.
나열된 메소드들은 반드시 모두 구현해야하나?!
위에서 언급했던 것과 같이 “그래픽스” 수업같은 경우에는 학생에 따라서 들을 수도 있지만 듣지 않을 수도 있습니다. 이와 같이 선택적인 메소드 구현을 위해서는 다음과 같이 @objc
키워드와 optional
을 이용하면 됩니다.
@objc protocol ComputerScienceStudent{
var name:String { get }
var laptop:String? { get set }
func doDataStructure()
func doOperatingSystem()
func doNetwork()
@objc optional func doGraphics()
}
이렇게 protocol
키워드 앞과 해당 함수의 앞에 위와 같이 @objc
와 optional
키워드를 붙여주면 됩니다.
마무리
나열된 메소드들은 반드시 모두 구현해야하나?!
프로토콜의 채택은 상속과 달리 class
뿐만아니라 enum
, struct
에도 적용이 가능합니다. 또한 delegation pattern
과 protocol oriented programming
에서도 프로토콜이 사용됩니다.
Swift에서 프로토콜은 굉장히 중요한 문법 중 하나입니다. 프로토콜을 반드시 제대로 이해하고 있어야 다른 문법과 디자인패턴도 이해하실 수 있습니다. 다음 시간에는 프로토콜에 대해 조금 더 알아보는 시간을 갖도록 하겠습니다. 감사합니다.
참고자료