어떤 기능에 적합한 특정 메서드, 프로퍼티 및 기타 요구 사항의 청사진Blueprint
를 의미한다.
클래스, 구조체, 열거형이 프로토콜을 채택
할 수 있고, 프로토콜에 정의된 요구사항의 실제 구현을 제공해야한다.
프로토콜의 요구 사항을 모두 충족하면 해당 프로토콜에 부합
하다고 한다.
var
로 선언 되어야 한다.// 프로토콜 정의
// 프로퍼티를 선언하여 값을 직접 정의하고, 메서드를 직접 구현 하는 것이 아니라
// 해당 프로토콜을 채택하려면 정해진 속성과 메소드를 무조건 갖고있어야한다는 약속을 정의해두는 것
protocol AProtocol {
var name: String { get }
}
// 프로토콜 채택 방법
// 채택할 프로토콜 이름을 쉼표`,`로 구분하여 명시
struct AStruct: AProtocol, BProtocol {
// var name: String 프로퍼티를 무조건 갖고있어야함
}
// 상속받는 클래스의 프로토콜 채택
// SubClass의 경우 SuperClass를 가장 앞에 명시한다.
class AClass: SuperClass, AProtocol {
}
// 프로토콜 프로퍼티는 무조건 var로 선언되어야함
protocol Person {
var name: String { get }
}
// 저장프로퍼티, 연산프로퍼티 둘 다 정의 가능하다.
// 저장 프로퍼티로 정의
class ABand: Person {
var name: String = "hansol"
}
// 연산 프로퍼티로 정의
class BBand: Person {
var name: String {
get {
return "hansol"
}
}
}
protocol AProtocol {
var age: Int { get }
}
// 저장 프로퍼티 let / var 둘 다 가능
class AClass: AProtocol {
var age: Int = 19
}
// 연산 프로퍼티 get / get & set 가능
class BClass: AProtocol {
var a: Int = 1
var age: Int {
get {
return 19
}
set {
self.a = newValue
}
}
}
protocol Person {
func speak() // 함수의 헤더부분만 작성
}
class AClass: Person {
func speak() {
print("can speak") // 함수의 바디부분 작성
}
}
let p = AClass()
p.speak() // 출력값: can speak
mutating
키워드 사용 시 프로토콜 자체에 추가한다.protocol Person {
mutating func changeName(changeName: String)
}
struct AStruct: Person {
var name: String = "hansol"
mutating func changeName(changeName: String) {
self.name = changeName
}
}
프로토콜에 @objc
선언 후 프로퍼티 앞에 @objc optional
을 붙일 경우 해당 프로퍼티는 필수가 아닌 optional로 바뀐다.
채택해주는 곳에서 꼭 선언해주지 않아도 된다. 하지만 @objc라는 문법을 사용하면 구조체에서는 채택하지 못하고 클래스에서만 채택할 수 있다.
@objc protocol AProtocol {
var name: String { get }
@objc optional var age: Int { get }
}
class SomeClass: AProtocol {
var name: String = ""
var age: NSNumber? = 19
}
let a = SomeClass()
print(a.name) // 출력값: sol
print(a.age) // 출력값: Optional(19)