Protocol?
- 특정 역할을 수행하기 위한 method, property, initializer 등의 요구사항을 정의한다.
📌 Protocol 정의
protocol 프로토콜이름 {
}
📌 Protocol 구현
protocol Talk {
// 1) 프로퍼티 요구
var topic: String { get set }
var language: String { get }
// 2) 매서드 요구
func talk()
// 3) 이니셜라이저 요구
init(topic: String, language: String)
}
→ 프로퍼티 요구에서, 꼭 var 키워드로 선언되어야 하며 get은 읽기 전용, get과 set이 함께 쓰일 경우 읽기+쓰기 모두 가능한 프로퍼티 여야한다.
💡 Protocol 을 채택한다 ?
- "구조체, 클래스, 열거형 등이 Protocol을 채택한다." 라고 하는데, 이 말은 꼭 갖추어야할 Protocol을 선택한다와 같다고 해석하면 될 거같다..!
Protocol 채택 방법
struct SomeStruct: AProtocol, BProtocol {
// 구조체 정의
}
// 상속받는 클래스의 프로토콜 채택
class SomeClass: SuperClass, AProtocol, BProtocol {
// 클래스 정의
}
→ SubClass일 경우, SuperClass를 꼭 Protocol 앞에 적어줘야 한다.
💡 Protocol 을 준수한다 ?
= 어떤 특정 Protocol의 요구사항을 모두 따른다.
자, 그럼 위에서 만들었던 Talk 프로토콜을 채택 및 준수해보자
// Person 구조체는 Talk 프로토콜을 채택
struct Person: Talk {
// 프로퍼티 요구를 준수
var topic: String
var language: String
// 매서드 요구를 준수
func talk() {
print("\(topic)에 대해 \(language)로 말하고 있다.")
}
// 이니셜라이저 요구를 준수
init(topic: String, language: String) {
self.topic = topic
self.language = language
}
}
위의 프로퍼티 요구를 연산 프로퍼티로 대체해보자 (= 연산 프로퍼티 대체 가능)
struct Person: Talk {
var subject: String = ""
var topic: String {
set {
self.subject = newValue
}
get {
return self.subject
}
}
var language: String { return "한국어" }
func talk() {
print("\(topic)에 대해 \(language)로 말하고 있다.")
}
init(topic: String, language: String) {
self.topic = topic
}
}
📌 프로토콜의 상속
- 프로토콜은 클래스와 다르게 다중 상속이 가능!
protocol Readable {
func read()
}
protocol Writeable {
func write()
}
protocol ReadSpeakable: Readable {
func speak()
}
protocol ReadWriteSpeakable: Readable, Writeable {
func speak()
}
struct SomeType: ReadWriteSpeakable {
func read() {
print("Read")
}
func write() {
print("Write")
}
func speak() {
print("Speak")
}
}
→ ReadWriteSpeakable 프로토콜은 Readable, Writeable로부터 read(), write() 메서드 요구까지 모두 상속받게 되어서 speak() 메서드만 요구해주면 된다.
📌 프로토콜 준수 확인
- is, as 연산자 사용 (is, as에 대한 포스팅)
class SuperClass: Readable {
func read() { }
}
class SubClass: SuperClass, Writeable, ReadSpeakable {
func write() { }
func speak() { }
}
let sup: SuperClass = SuperClass()
let sub: SubClass = SubClass()
var someAny: Any = sup
someAny is Readable // true
someAny is ReadSpeakable // false
someAny = sub
someAny is Readable // true
someAny is ReadSpeakable // true
someAny = sup
// someAny가 Readable 프로토콜을 따른다면 someReadable도 Readable 프로토콜을 따를 수 있게 됨
if let someReadable: Readable = someAny as? Readable {
someReadable.read()
} // read
if let someReadSpeakable: ReadSpeakable = someAny as? ReadSpeakable {
someReadSpeakable.speak()
} // 동작하지 않음
someAny = sub
if let someReadable: Readable = someAny as? Readable {
someReadable.read()
} // read
Reference
야곰의 스위프트 기본 문법 강좌
'Swift' 카테고리의 다른 글
[Swift] 모나드, 옵셔널 ! (0) | 2022.09.17 |
---|---|
[Swift] Extension (0) | 2022.08.24 |
[Swift] lazy? (0) | 2022.08.21 |
[Swift] Any / AnyObject (0) | 2022.08.14 |
[Swift] 타입캐스팅 : is, as (0) | 2022.08.13 |