0411(목) 프로토콜 - hwj0623/ios_swift GitHub Wiki
Reference
야곰의 블로그 Swift Protocol 이해하기 #1 Swift에서 프로토콜 중심 프로그래밍(POP)하기
프로토콜 정의
- 인스턴스끼리 서로 정보를 주고 받기 위해 합의한 규약, 명세 등을 의미한다.
프로토콜의 특징
-
특정 역할을 수행하기 위한
메서드
,프로퍼티
,이니셜라이저
등의 요구사항을 정의한다.- 메서드는 선언만 하고, 함수를 구현하지는 않는다.
- 프로퍼티도 선언만 한다.
- 대신
readable
한 내용은get
,writable
도 가능한 프로퍼티는set
으로 지정한다.
- 대신
-
특정
구조체
,클래스
,열거형
에 대해특정 기능 등을 구현할 것을 강요
하는 것 -
구조체, 클래스, 열거형은 프로토콜을
채택(Adopted)
해서 프로토콜의 요구사항을 실제로 구현할 수 있습니다. -
어떤 프로토콜의 요구사항을 모두 따르는 타입은 그
‘프로토콜을 준수한다(Conform)’
고 표현합니다. -
프로토콜의 요구사항을 충족시키려면 프로토콜이 제시하는 기능을 모두 구현해야 합니다.
Basic Example (1)
/// 프로토콜 : '~할 수 있는'의 형식으로 네이밍한다.
protocol SecretaryQualifiable {
func manageSchedule () // 함수를 구현하지는 않는다.
func brewCoffee()
func drive()
var certification: String { get } // get - readable property
var drivingLicense: String { get }
}
/// 프로토콜 SecretaryQualifiable를 채택한 구조체 Secretary
struct Secretary: SecretaryQualifiable {
func manageSchedule() {
print("Managing schedule well done!")
}
func brewCoffee() {
print("I drip a any cup of coffee")
}
func drive() {
print("drive anywhere")
}
var certification: String
var drivingLicense: String
}
/// Assistant는 SecretaryQualifiable 프로토콜을 "채택"했다
struct Assistant: SecretaryQualifiable {
func manageSchedule() {
print("Managing schedule so so!")
}
func brewCoffee() {
print("I drip only cold brew coffee")
}
func drive() {
print("drive in highway")
}
var certification: String
var drivingLicense: String
}
struct CEO {
var secretary: SecretaryQualifiable // 프로토콜에 부합하는 자는 모두 secretary가 될 수 있다.
}
/// 프로토콜을 "conform(준수)" 한 구조체 선언 및 초기화
let secretary1: Secretary = Secretary(certification: "KoreaUniv_Bachelor", drivingLicense: "2종 자동")
let secretary2: Assistant = Assistant(certification: "KoreaUniv_Master", drivingLicense: "1종 자동")
/// Secretary와 Assistant 모두 SecretaryQualifiable을 따르므로 아래의 코드는 이상없이 컴파일된다.
var master: CEO = CEO(secretary: secretary1)
master.secretary = secretary2
Basic Example (2)
- 프로토콜은 다른 프로토콜을
상속
받을 수 있다. - 프로토콜의 프로퍼티가 겹치는 경우, Type이 다르다면 구조체 등에서 프로퍼티 충돌이 일어난다.
- 상속받은 프로토콜의 프로퍼티명과 중복되지 않도록 한다.
protocol Drivable{
var drivingLicense: Int { get }
func drive()
}
protocol Brewable {
func brewCoffee()
}
/// Drivable, Brewable 을 "상속"받은 프로토콜
protocol SecretaryQualifiable: Drivable, Brewable {
func manageSchedule ()
func brewCoffee()
func drive()
var certification: String { get }
// 해당 프로퍼티가 상속받은 프로퍼티 (Int형 drivingLicense)와 충돌한다.
var drivingLicense: String { get }
}
Basic Example (3)
- 아래와 같이 비서의 조건이 Drivable과 Brewable이라면, 이를 상속한 SecretaryQualifiable 를 구현하는 것으로도 구조체가 비서가 될 수 있다.
import UIKit
/// 프로토콜의 프로퍼티가 겹치는 경우는 구조체 등에서 프로퍼티 충돌이 일어난다.
protocol Drivable{
func drive()
var drivingLicense: String { get }
}
/// 프로토콜
protocol Brewable {
func brewCoffee()
}
/// 프로토콜 : '~할 수 있는'의 형식으로 네이밍
protocol SecretaryQualifiable: Drivable, Brewable { // Drivable, Brewable 을 "상속"받은 프로토콜
func manageSchedule () // 함수를 구현하지 않는다.
/// get - readable property
var certification: String { get }
}
struct Secretary: SecretaryQualifiable{ /// Secretary는 Drivable, Brewable 프로토콜을 "adopt"했다
func manageSchedule() {
print("Mananging schedule welldone!")
}
func brewCoffee() {
print("I drip a any cup of coffee")
}
func drive() {
print("drive anywhere")
}
var certification: String
var drivingLicense: String
}
/// Secretary는 SecretaryQualifiable 프로토콜을 "채택"했다
struct Assistant: SecretaryQualifiable {
func manageSchedule() {
print("Mananging schedule so so!")
}
func brewCoffee() {
print("I drip only cold brew coffe")
}
func drive() {
print("drive in highway")
}
var certification: String
var drivingLicense: String
}
struct CEO {
var secretary: Drivable&Brewable
}
/// 프로토콜을 "conform(준수)" 한 구조체 선언 및 초기화
let secretary1: Secretary = Secretary(certification: "KoreaUniv_Bachelor", drivingLicense: "2종 자동")
let secretary2: Assistant = Assistant(certification: "KoreaUniv_Master", drivingLicense: "1종 자동")
var master: CEO = CEO(secretary: secretary1)
master.secretary = secretary2