프로토콜
자바의 interface와 같은 기능을 하는, 메소드 호출 규격을 약속한 것이다. 그러므로 메소드의 선언만 작성하며 클래스나 구조체에 채택되어 사용한다.
protocol Singing {
func sing()
}
protocol Dancing {
func dance()
}
// static method 선언
protocol Species {
static func species() -> String
}
// 클래스에 프로토콜 적용
class Bird : Singing {
func sing() {
print("hahah")
}
}
// 여러 프로토콜 적용
class Cat : Singing, Dancing, Species {
func sing() {
print("hahahen")
}
func dance() {
print("dand")
}
static func species() -> String {
return "haha"
}
}
프로퍼티
프로토콜에 프로퍼티의 get/set 행위를 선언할 수 있다. 프로토콜의 프로퍼티는 저장 프로퍼티나 계산 프로퍼티로 구현한다. 계산 프로퍼티로 작성하는 경우 프로토콜의 get/set 범위와 같거나 더 넓은 범위로 작성해야 한다.
protocol Holding {
var duration : Int { get set }
}
class Hold: Holding {
var duration : Int = 0
}
class Hold: Holding {
var duration : Int {
get {
return 1
}
set {
self.duration = newValue
}
}
}
초기화 메소드 선언
프로토콜에 초기화 메소드 init을 선언할 수 있다. 이 프로토콜을 채택한 클래스에서 초기화 메소드를 작성할 때는 required 키워드를 이용해서 작성한다. 프로토콜에 선언하는 초기화 메소드는 Failable Initializer도 가능하다. 이 초기화 메소드는 Failable이나 일반 초기화 메소드로 작성한다.
프로토콜 타입과 상속
프로토콜을 타입으로 사용하면 프로토콜에 정의된 메소드나 프로퍼티만 사용할 수 있다.
// 3개의 프로토콜이 적용된 Cat()에서 Singing프로토콜의 프로퍼티와 메소드만을 사용한다.
var singingAnimal : Singing = Cat()
singingAnimal.sing()
singingAnimal.dance() // error
프로토콜은 다른 프로토콜을 상속할 수 있다.
클래스 전용 프로토콜
프로토콜은 클래스와 구조체, enum 타입에 채택할 수 있다. 만약 클래스에서만 채택하도록 작성하려면 프로토콜 선언에 class 키워드를 프로토콜 이름 뒤에 붙인다. 다른 프로토콜을 상속할 때에는 부모 프로토콜 이름보다 먼저 작성한다.
// 클래스 전용 프로토콜 선언
protocol Move : class, Singing {}
struct Action : Move { } // error
class Action2 : Move {}
필수 항목과 선택 항목
프로토콜의 항목에 optional로 선언하면 해당 프로퍼티나 메소드를 선택적으로 작성해도 된다. 단 선택 항목을 사용하려면 @objc 키워드를 프로토콜 정의 앞에 적어야 한다. @objc는 스위프트로 작성한 항목을 Objective-C 런타임에서 사용하도록 하는 키워드이고, 이 프로토콜을 채택한 클래스는 NSObject의 자식 클래스로 생성한다. 구조체나 열거형에서 @objc로 작성한 프로토콜을 채택할 수 없다.
@objc protocol Baking {
func baking() // 필수 구현 메소드
optional func makeDough() // 선택 구현 메소드
}
댓글