-
Swift - Protocol ExtensionProgramming/Swift 2022. 1. 12. 18:50
안녕하세요 BeePeach입니다 :)
오늘 공부해볼 내용은 Protocol Extension입니다.
Protocol도 Type이기 때문에 extension을 이용해서 확장시킬 수 있습니다.
Extension을 활용하면 아래의 기능을 추가시킬 수 있습니다.
- Protocol Default Implenentation(기본구현) 추가
- Constraints (제약) 추가
그럼 하나하나씩 공부해볼까요??
Extension
우리가 이전에 배웠던 extension의 가장 기본적인 사용법은 Type에 없던 멤버들을 추가시키는 것이었습니다.
Extension을 이용하면 protocol에 computed property, method, subscript를 추가시킬 수 있습니다.
그럼 여기서도 protocol에 없던 요구사항을 추가시켜보도록 하겠습니다.
Animal이라는 프로토콜을 구현하고 extension으로 여기에 introdue라는 메서드를 요구사항으로 추가시켜보려 했습니다.
음.. 그런데 에러가 발생하네요??
에러 메시지를 보니 {}, 즉 function body가 없다고 합니다.
이전에 protocol에 대해서 배웠을 때는 method 요구사항은 분명 헤더만 작성해야 하는 게 올바른 문법이었습니다.
하지만 extension을 이용하여 요구사항을 추가시킬 때는 기존에 protocol에서 요구사항을 정의하듯 추가시키면 안 됩니다.
그럼 어떻게 추가시켜야 할까요??
Protocol Default Implementation
Extension으로 protocol을 확장하는 것은 요구사항만을 추가시키는 것이 아닙니다.
요구사항을 추가시키는 게 아니라 요구사항의 기본 구현을 추가시키는 것입니다.
그래서 없던 요구사항을 추가시킬 때도 기본 구현을 같이 작성해줘야 합니다.
이해가 잘 안 된다면 예제를 보면 이해가 될 거예요.
이번에는 우리가 class나 struct에서 구현하는 것처럼 introduce() 메서드를 구현했습니다.
헤더만 정의한 게 아니라 내부 구현까지 모두 했습니다.
그럼 기본 구현을 추가시킨다는 의미가 무엇을 의미하는지 예제를 보도록 하겠습니다.
Dog 클래스는 Animal 프로토콜을 채용하고 있습니다.
필수 요구사항인 name, age 프로퍼티를 정의했고 인스턴스를 생성하기 위한 init(name:age:)도 정의했습니다.
extension에서 우리가 추가한 introduce 메서드는 구현하지 않았습니다.
그런데 Dog 인스턴스를 생성하고 introduce 메서드를 호출해보니 에러가 나지 않고 실행되는 것을 확인할 수 있습니다.
이렇게 extension을 이용해서 protocol의 기본 구현을 추가할 수 있습니다.그리고 기본구현을 한 멤버는 protocol을 채용하는 Type에서 기능을 구현하지 않아도 사용할 수 있게 됩니다.
이번에는 Dog와 똑같은 Cat 클래스를 정의했습니다.
그런데 이번에는 기본 구현으로 정의된 introduce 메서드를 다르게 구현하고 싶어서 Cat을 정의할 때 introdue() 메서드를 다시 정의해주었습니다.
그리고 출력 결과를 보니 기본 구현은 무시되고 Cat class에서 정의한 대로 출력이 됐습니다.
이렇게 extension을 이용하여 기본 구현을 추가시켰을 때 Type에서 구현하지 않으면 기본 구현대로 동작하고 Type에서 또 정의를 해주면 Type에서 정의한 대로 동작하게 됩니다.
흡사 override와 비슷하죠. 하지만 상속이 아니므로 override 키워드는 붙이지 않습니다.
물론 기존에 없던 요구사항뿐만 아니라 존재하던 요구사항에 기본 구현을 추가시킬 수도 있습니다.
name 프로퍼티에 기본값을 구현해놓으니 Bird class에서 name을 구현하지 않아도 에러가 나지 않고 기본 값이 할당된 것을 확인할 수 있습니다.
Add Constraint
Extension을 이용해서 제약을 추가할 수도 있습니다.
제약을 추가하면 extension으로 추가한 기본 구현을 조건을 만족하는 Type에만 추가가 되도록 할 수 있습니다.
다시 말해 protocol을 채용하는 모든 Type이 추가된 기본 구현을 이용할 수 있었죠??
하지만 제약을 추가하면 특정 Type만 이용할 수 있도록 하는 것입니다.
사용 방법은 Protocol이름 뒤에 where과 조건을 적어주면 됩니다.
Collection도 프로토콜이죠?? (Collection이 뭔지 기억이 안 나신다면 여기를 참고해주세요.)
extension으로 Collection에 isNumbers라는 메서드를 추가시켰습니다.
그냥 print로 It's numbers를 출력하는 간단한 메서드입니다.
제약이 없다면 이 메서드는 [String]에서도 사용할 수 있게 돼서 문자열 배열이지만 It's numbers라는 로그가 출력됩니다.
이러면 안 되겠죠??
그래서 Protocol 옆에 where과 함께 Type parameter인 Element가 Numeric protocol을 채용할 경우에만 기본 구현이 추가되도록 제약을 주었습니다. (이 부분은 Generic을 아셔야 이해가 됩니다.)
그랬더니 [Int]에서는 isNumbers() 메서드가 호출이 되고 [String]에서는 inNumbers() 메서드가 호출되지 않는 것을 확인할 수 있습니다.
참고자료
여러분의 새로운 도전을 응원합니다 | 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 - Comparable Protocol (0) 2022.01.15 Swift - Equatable Protocol (0) 2022.01.14 Swift - Protocol Optional Requirement (0) 2022.01.04 Swift - Protocol Composition (0) 2022.01.03 Swift - Protocol Inheritance (0) 2022.01.02