Swift/문법
프로토콜(protocol)
khon98
2021. 1. 30. 12:11
프로토콜
- 특정 역할을 수행하기 위한 메서드, 프로퍼티, 이니셜 라이저 등의 요구사항을 정의
- 구조체, 클래스, 열거형은 프로토콜을 채택해서 프로토콜의 요구사항을 실제로 구현할 수 있음
- 어떤 프로토콜의 요구사항을 모두 따르는 타입은 '프로토콜을 준수한다'라고 표현함
- 프로토콜의 요구사항을 충족시키려면 프로토콜이 제시하는 기능을 모두 구현해야 함
protocol 프로토콜 이름 {
정의부
}
프로토콜 상속
- 프로토콜은 클래스와 다르게 다중 상속이 가능함
protocol 프로토콜 이름 : 부모 프로토콜 이름 목록 {
정의부
}
클래스 상속과 프로토콜
- 클래스에서 상속과 프로토콜 채택을 동시에 하려면 상속받으려는 클래스를 먼저 명시하고 그 뒤에 채택할 프로토콜 목록을 작성함
프로토콜 준수 확인
- 인스턴스가 특정 프로토콜을 준수하는지 확인할 수 있음
- is, as 연산자 사용
protocol Talkable {
// 프로퍼티 요구
// 프로퍼티 요구는 항상 var 키워드를 사용
// get은 읽기만 가능해도 상관 없다는 뜻이며 get과 set을 모두 명시하면 읽기 쓰기 모두 가능
var topic: String { get set }
var language: String { get }
// 메서드 요구
func talk() // 타입에서 구현
// 이니셜라이저 요구
init(topic: String, language: String)
}
// 프로토콜 채택 및 준수
// Person 구조체는 Talkable 프로토콜을 채택
struct Person: Talkable {
var topic: String // 읽기, 쓰기 모두 가능한 변수로 선언
let language: String // 읽기 전용, 상수 / var로 바꿔도 상관 없음
// 메서드 구현
func talk() {
print("\(topic)에 대해 \(language)로 말합니다")
}
// 이니셜라이저 구현
init(topic: String, language: String) {
self.topic = topic
self.language = language
}
}
protocol Readable {
func read()
}
protocol Writealbe {
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")
}
}
// 클래스 상속과 프로토콜
class SuperClass: Readable {
func read() { print("read") }
}
class SubClass: SuperClass, Writeable, ReadSpeakable {
func write() { print("write") }
func speak() { print("speak") }
}
// 프로토콜 준수 확인
let sup: SuperClass = SuperClass()
let sub: SubClass = SubClass()
var someAny: Any = sup
someAny is Readable // true
someAny is ReadSpeakable // true
someAny = sub
someAny is Readable // true
someAny is ReadSpeakable // true
someAny = sup
if let someReadable: Readable = someAny as? Readable {
someReadable.read()
} // read
if let someReadSpeakable: ReadSpeakable = someAny as? ReadSpeakable {
someReadSpeakable.speak()
} // 동작하지 않음
if let someReadable: Readable = someAny as? Readable {
someReadable.read()
} // read