본문 바로가기

Swift

[Swift] Protocol

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