ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift - Protocol Initializer , Subscript
    Programming/Swift 2021. 12. 28. 18:28

     

     

    안녕하세요 BeePeach입니다 :)

     

    이번 포스팅에서는 지난번 포스팅에 이어 Protocol에서 Initializer와 Subscript를 정의하는 방법에 대해서 공부해보도록 하겠습니다.

     

     


     

    Initializer

     

    Init을 정의하는 방법도 마찬가지로 body를 제외하고 헤더만 적어주면 됩니다.

    어려울 게 없으니 바로 예시를 보겠습니다.

     

     

    Figure라는 프로토콜에 name 프로퍼티와 init(name:)을 정의했습니다.

    그리고 Triangle이라는 struct를 정의했는데요 init(name:)을 요구하고 있으니 init(name:)을 정의하고 내부 구현은 우리가 원하는 대로 할 수 있습니다.

    이 코드에서 짚고 넘어갈 부분은 protocol에서 name 프로퍼티와 init(name:)을 요구하고 있고 Triangle은 구조체이므로 name프로퍼티만 선언해주면 Memberwise initiailizer로 init(name:)이 자동으로 제공되죠?? 그래서 init(name:)을 생략해도 protocol 요구사항을 만족하지 못했다는 에러가 발생하지 않습니다.

     

     

     init(name:)을 생략해도 에러가 발생하지 않죠?? 이렇게 init이 자동으로 생성된것도 protocol 요구사항을 만족한 것으로 취급합니다.

     

    Struct는 상속이 없으므로 init을 정의하는게 쉽고 Class는 상속으로 인해 init의 구현이 복잡했던 게 기억나시나요??

    (기억이 안나신다면 여기를 참고해주세요.)

     

    Protocol의 init 요구사항을 class에서 만족시키려면 어떻게 해야 할까요???

    Designated, Convenience 등등 다 구별을 해줘야 할까요???

     

    정답은 바로 그렇지 않습니다! 입니다.

    Protocol의 요구사항을 만족시킬 init을 구현할 때 designated init인지 convenience init인지 전혀 중요하지 않습니다. 

    둘 중 무엇을 쓰던 상관없습니다. 그냥 Protocol에서 정의한 파라미터만 지켜주면 됩니다.

    하지만 한 가지 추가해야 하는 게 있는데요.

    바로 required 키워드입니다.

     

    Required init은 반드시 subclass에서 구현을 해야 했죠??

    Class에는 상속이 존재하고 protocol에서 요구하는 init을 구현하기 위해서는 required 키워드를 사용해서 혹시 존재하게 될 subclass에서도 반드시 protocol 요구 init을 구현하도록 명시해줘야 합니다.

     

     

    백문이불여일견 바로 작성해보면 되겠죠??

    넵 바로 required를 붙이라는 에러가 나오는 것을 확인할 수 있습니다.

     

     

    이렇게 requried만 붙여주면 해결이 됩니다.

    그리고 Elipse class는 Circle을 상속하고 있습니다. Circle에서는 이미 Figure protocol을 채용하고 있죠??

    그래서 Elipse에서는 Figure를 또 적어주지 않습니다. Circle을 상속하면 자동적으로 Figure를 채용하게 됩니다.

    그렇기 때문에 Elipse에서 init(name:)을 또 구현해준 것을 확인할 수 있습니다. 이때도 required 키워드는 꼭 작성해야 합니다.

     

    그럼 몇 가지 주의해야 할 예시를 또 보도록 하겠습니다.

     

     

    만약 subClass에서 프로토콜의 요구 init을 구현하려고 했는데 superClass에서 먼저 작성이 되어있다면 override를 해야겠죠??

    그때는 override와 required를 같이 적어줍니다. 둘의 순서는 상관없습니다. 두 키워드가 모두 들어가기만 하면 됩니다.

     

    주의하실 점은 required init은 override 키워드를 작성하지 않는다면서?!?라고 생각하실 수 있는데 프로토콜을 채용할 때는 조금 달라집니다. override 키워드를 작성하지 않는 경우는 위의 Circler과 Elipse의 경우입니다. 

    두 경우를 헷갈리기 쉬운데 정확하게 기억하지 못해도 Error을 알아서 잘 알려주기 때문에 큰 걱정하실 필요는 없습니다.

     

    Protocol의 요구 init을 구현하는데 required를 붙이지 않아도 되는 경우가 1가지 있습니다.

    required를 요구하는 이유가 'Class에는 상속이 존재하고 protocol에서 요구하는 init을 구현하기 위해서는 required 키워드를 사용해서 혹시 존재하게 될 subclass에서도 반드시 protocol 요구 init을 구현하도록 명시해줘야 합니다.'라고 설명했었죠???

     

    그럼 만약 subclass가 절대 존재할 이유가 없다면? 그럼 required가 필요 없겠죠??

     

     

    required 키워드가 없어도 에러가 나지 않는 것을 확인할 수 있습니다.

     

     


     

    Failable Initializer

     

     

    Protocol에서 init을 정의할 때 non-failable init만 정의가 가능한 게 아니라 failable init도 정의가 가능합니다.

    구현 방식은 init과 똑같이 body는 생략해줍니다. 대신 ?과 !가 포함됩니다.

    나머지는 다를 게 없습니다.

    그럼 바로 예시를 보도록 하겠습니다.

     

     

    Failable이라는 프로토콜에는 init?(name:)이 정의되어 있습니다.

    그렇다면 이 프로토콜을 채용하는 type에서는 init?(name:)을 구현해야겠죠??

     

    Desk에서는 그대로 init?(name:)을 구현했습니다.

    그런데 Chair에서는 init(name:)을 구현했습니다. 그래도 에러가 나지 않았네요??

     

    Protocol의 요구 failable init은 non-failable init 또는 failable init으로 만족시키면 됩니다.

    Failable init은 성공할 수 도 실패할 수 도 있으므로 무조건 성공한다 해서 문제가 될 건 없잖아요??

     

    하지만 반대의 경우는 다릅니다.

     

     

    Protocl에 non-failable init으로 정의되어 있는 경우에는 반드시 non-failable init으로 구현을 해줘야 합니다.

    Non-Failable init은 반드시 초기화가 완료돼야 하기 때문에 실패란 존재하면 안 되기 때문입니다.

     

     


     

    Subscript

     

    Protocol에서 Subscript를 정의할 때도 마찬가지로 구현 부분은 생략합니다.

     

    Subscript를 구현할 때 getter setter를 구분해줬던 게 기억나시나요??

    Protocol에서 정의할 때는 헤더 부분은 똑같지만 body에는 프로퍼티와 비슷하게 get과 set을 작성합니다.

     

    간단한 예시를 보도록 하겠습니다.

     

     

    크게 의미 있는 코드는 아닙니다.

    Indexable이라는 Protocol에 subscript가 정의되어 있습니다.

    Protocol에 정의가 된 것처럼 파라미터와 returnType을 지켜서 CustomData에 subscript를 구현했습니다.

    그리고 요구사항은 { get }으로 돼있지만 최소 요구사항 이므로 setter를 추가시켜줘도 문제가 없는 것을 확인할 수 있습니다.

     

     


     

    참고자료

     

    https://kxcoding.com

     

    여러분의 새로운 도전을 응원합니다 | KxCoding

    Mastering SwiftUI 더 적은 코드로, 더 멋진 UI 만들기

    kxcoding.com

     

     

    https://docs.swift.org/swift-book/LanguageGuide/Protocols.html

     

    Protocols — The Swift Programming Language (Swift 5.6)

    Protocols A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of tho

    docs.swift.org

     

     

     

    728x90

    'Programming > Swift' 카테고리의 다른 글

    Swift - Protocol Inheritance  (0) 2022.01.02
    Swift - Protocol as Type  (0) 2021.12.29
    Swift - Protocol  (0) 2021.12.22
    Swift - Extension  (0) 2021.12.20
    Swift - Deinitializer  (0) 2021.12.19
Designed by Tistory.