프로토콜이란 어떤 기준을 만족하거나 특수한 목적을 달성하기 위해 구현해야하는 메소드와 프로퍼티의 목록이다.
프로토콜에 선언된 프로퍼티나 메소드의 형식을 프로토콜 명세라고 부르고, 실질적 내용의 작성을 프로토콜 구현이라고 부른다.
import Foundation
protocol SomeProtocol {
/// 프로토콜 프로퍼티
// 저장 프로퍼티의 경우 반드시 get/set 모두 구현해야함! get만 구현 불가 -> p.577
// but swift.org에서는 구현 가능 하다고 나와있음
// 실제로 구현 가능 -> 그러면 get set과 get의 차이가 뭐임 .. ?!
// 필수 프로퍼티는 항상 var로 선언해야 한다.
var name: String { get set }
/*
computed property일 경우 get or get/set 으로 설정해 준 뒤에 설정 가능
*/
var desc: String { get }
/// 프로토콜 메소드
// 실제 함수 내용인 {} 안을 작성할 수 없다
// static 키워드를 붙인 경우 class 키워드로 변경이 가능하다.
// mutating 키워드가 붙지 않았는데 struct에서 implement할 때 mutating 키워드를 붙일 경우 에러
func execute(cmd: String)
func showPort(p: Int) -> String
/// Initializer
// 프로토콜에서 초기자를 구현할 경우 class에서는 required 키워드를 붙여줘야한다.
init()
}
struct Person: SomeProtocol {
var name: String
var desc: String
func execute(cmd: String) {
}
func showPort(p: Int) -> String {
return ""
}
init() {
self.name = ""
self.desc = ""
}
init(name: String, desc: String) {
self.name = name
self.desc = desc
}
}
let john = Person(name: "john", desc: "stored property")
print(john.desc)
// 타입으로써의 프로토콜
/**
다음과 같이 타입 사용이 허용되는 모든 곳에 프로토콜 사용 가능
프로토콜을 타입으로 활용하여 Delegate Pattern 적용
- 함수, 메소드, 이니셜라이저의 파라미터 타입 혹은 리턴 타입
- 상수, 변수, 프로퍼티의 타입
- 컨테이너인 배열, 사전 등의 아이템 타입
*/
// 조건적으로 프로토콜 따르기
// where문을 사용한다.
extension Array: SomeProtocol where Element: SomeProtocol {
// do something
}
// extension으로 프로토콜 채택
struct Hamster {
var name: String
}
extension Hamster: SomeProtocol {} // implement Protocol
// 프로토콜 상속
protocol A {
func doA()
}
protocol B: A {
func doB()
}
protocol C: B {
func doC()
}
class ABC: C {
func doC() {
}
func doA() {
}
func doB() {
}
}
let test: A = ABC() // doA만 사용 가능
let testC: C = ABC() // doA,B,C 다 사용 가능
// 클래스 전용 프로토콜
protocol ClassOnlyProtocol: AnyObject {
// only for classes
}
// Optional protocol
@objc protocol ObtionalProtocol {
@objc optional func hello()
}