iOS 공부하는 감자

Day11) 프로토콜, 익스텐션 본문

22 베이직 챌린지

Day11) 프로토콜, 익스텐션

DongTaTo 2022. 1. 13. 23:11
반응형

프로토콜

  • 특정 역할을 수행하기 위한 메서드, 프로퍼티, 이니셜라이저 등의 요구사항을 정의한다.
  • 구조체, 클래스, 열거형은 프로토콜을 채택(Adopted)해서 프로토콜의 요구사항을 구현할 수 있다.
  • 특정 프로토콜의 요구사항을 모두 따르는 타입은 그 '프로토콜을 준수한다(Conform)고 표현한다.
  • 프로토콜을 준수하려면 프로토콜이 제시하는 기능을 모두 구현해야 한다.
  • protocol 프로토콜 이름 {
        기능 정의
    }
  • // 프로토콜 작성 예시
    
    protocol Talkable {
    //    프로퍼티 요구
    //    프로퍼티 요구는 항상 var 키워드를 사용
    //    get만 사용: 읽기만 가능해도 상관없다.
    //    get, set 모두 명시 : 읽기와 쓰기 모두 가능한 프로퍼티로 구현해야 한다.
        var topic: String {get set}
        var language: String {get}
        
        // 메서드 요구
        func talk()
        
        // 이니셜라이저 요구
        init (topit: String, language: String)
    }
  • // 프로토콜 채택 및 준수 예시
    
    struct Person: Talkable {
        var topic: String
        // 프로토콜에서 읽기만 가능해도 상관없다고 요구했으니, 읽기 전용인 let(상수)이 아니라 var(변수)로 프로퍼티를 정의해도 괜찮다.
        let language: String
    
        
        // 읽기전용 프로퍼티, 읽기와 쓰기 모두 가능한 프로퍼티는 둘 다 연산 프로퍼티로 대체할 수 있다.
    //    var language: String {"Korean"}  // 읽기전용
    //
    //    var subject: String = ""
    //    var topic: String {              // 읽기, 쓰기 모두 가능
    //        get {
    //            self.subject
    //        }
    //        set {
    //            self.subject = newValue
    //        }
    //    }
        
        
        // 메서드 준수
        func talk() {
            print("\(topic)에 대해 \(language)로 말합니다.")
        }
        
        
        // 이니셜라이저 준수
        init(topit: String, language: String) {
            self.topic = topit
            self.language = language
        }
    }

 

프로토콜의 상속

  • 프로토콜은 클래스와 다르게 다중상속이 가능하다.
  • protocol 프로토콜 이름: 부모 프로토콜 이름 목록 {
        기능 정의
    }
  • protocol Readable {
        func read()
    }
    
    protocol Writeable {
        func write()
    }
    
    protocol ReadSpeakable: Readable {
    //    func read()
        func speak()
    }
    
    // 프로토콜 다중 상속
    protocol ReadWriteSpeakable: ReadSpeakable, Writeable {
    //    func read()
    //    func write()
    //    func speak()
    }
    
    struct Humen: 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")
        }
    //    func read() {
    //        print("read")
    //    }
    }

 

 

(인스턴스가) 특정 프로토콜을 준수하는지 확인

  • 타입캐스팅에서 사용했던 is, as 연산자를 통해 확인이 가능하다.
  • // 인스턴스 생성
    let superInstance: SuperClass = SuperClass()
    let subInstance: SubClass = SubClass()
    
    var someAny: Any = superInstance
    someAny is Readable             // true
    someAny is ReadSpeakable        // false
    
    someAny = subInstance
    someAny is Readable             // true
    someAny is ReadSpeakable        // true
    
    
    someAny = superInstance
    
    if let someReadable: Readable = someAny as? Readable {
        someReadable.read()
        // read
    }
    
    if let someReadSpeakable: ReadSpeakable = someAny as? ReadSpeakable {
        someReadSpeakable.speak()
        // 동작하지 않음
    }
    
    
    someAny = subInstance
    
    if let someReadable: Readable = someAny as? Readable {
        someReadable.read()
        // read
    }

 

 

프로토콜을 사용함으로써...

  1. 각 타입을 구현하는 입장에서는 클래스, 구조체, 열거형에서 구현해야 할 내용을 강요받는다. (프로토콜의 내용을 준수해야 하니까)
  2. 사용자의 입장에서는(인스턴스를 사용하는 입장) 어떤 프로토콜을 준수하는지 확인하고, 어떤 기능들이 수행 가능할지 명확하게 알 수 있다.
  3. 컴파일러도 해당 타입의 인스턴스가 어떤 기능을 수행 가능할지 쉽게 파악이 가능

 

 

 

 


익스텐션

  • 클래스, 구조체, 열거형, 프로토콜 타입에 새로운 기능을 추가할 수 있는 기능이다.
  • 해당 타입의 상세 구현 내용을 알지 못하더라도, 타입의 이름만 알고 있다면 해당 타입의 기능을 확장할 수 있다.

 

 

익스텐션으로 추가할 수 있는 기능들

  • 연산 타입 프로퍼티 / 연산 인스턴스 프로퍼티
  • 타입 메서드 / 인스턴스 메서드
  • 이니셜라이저
  • 서브스크립트
  • 중첩 타입
  • 특정 프로토콜을 준수할 수 있도록 기능 추가
  • 기존에 존재하는 기능을 재정의하는 것은 불가능

 

 

익스텐션 정의 문법

  • 기본 문법
  • extension 확장할 타입 이름 {
        타입에 추가할 기능 구현
    }

 

 

  • 기존 타입이 추가적으로 다른 프로토콜을 채택할 수 있도록 확장
  • extension 확장할 타입 이름: 프로토콜1, 프로토콜2 ... {
        추가한 프로토콜(들)의 요구사항 구현
    }

 

 


알고리즘

https://co-dong.tistory.com/20

 

2016년

문제 설명 2016년 1월 1일은 금요일입니다. 2016년 a월 b일은 무슨 요일일까요? 두 수 a ,b를 입력받아 2016년 a월 b일이 무슨 요일인지 리턴하는 함수, solution을 완성하세요. 요일의 이름은 일요일부터

co-dong.tistory.com

 

 

 

 

 

반응형

'22 베이직 챌린지' 카테고리의 다른 글

Day13) 타입캐스팅  (0) 2022.01.15
Day12) 옵셔널  (0) 2022.01.14
Day10) 클래스와 상속  (0) 2022.01.12
Day9) 메서드, 접근제한자, Static  (1) 2022.01.11
Day8) 프로퍼티, 연산 프로퍼티  (0) 2022.01.10