-
Swift - ProtocolProgramming/Swift 2021. 12. 22. 13:05
안녕하세요 BeePeach입니다 :)
이번에 공부해볼 내용은 Protocol(프로토콜)입니다.
먼저 Protocol의 사전적 정의부터 한 번 알아볼까요??
사전적 의미는 규약, 조약이라고 볼 수 있겠네요.
규약이란 서로 무엇인가를 위해서 약속하고 지키는 것을 의미하죠???
이러한 의미로 Protocol이란 Type(class, struct, enum)이 어떠한 기능을 구현하기 위해서 필요한 멤버(propert, method, init...)들을 선언해야 한다고 약속하는 것입니다.
다시 말해 Protocol은 Type이 특정 기능을 구현하기 위한 멤버들의 bluePrint(청사진)을 정의합니다.
청사진만 제공하는 것이므로 기능을 구현하지는 않습니다.
어떠한 멤버들이 이러한 형태로 구현됐으면 좋겠어!라는 느낌으로 정의만 해주고 세부적인 구현은 protocol을 채용한 Type에서 구현합니다.
그럼 구현하는 방법을 살펴보도록 하겠습니다!
Syntax
문법은 Type을 정의하는 방법과 유사합니다.
그리고 Swift convention에 따라서 protocol의 이름은 UpperCamelCase로 작성해주어야 합니다. 그리고 안에 정의되는 멤버들은 lowerCamelCase로 작성해줍니다.
위에서 설명할때 Adopt(채택, 채용)이라는 단어를 사용했습니다.
Class, struct, enum과 같은 Type이 protocol의 요구사항을 구현하기 위해서 규약을 지키는 것을 채택, 채용한다고 표현합니다.
그리고 모든 요구사항을 만족하면 Conform(준수하다, 따르다) 한다고 표현합니다.
그럼 Type들의 protocol을 어떻게 채용할까요?? 그냥 다짜고짜 protocol에 정의된 멤버를 구현한다고 채용되는 건 아닐 거잖아요?
Class에서 상속을 하는 것처럼 TypeName옆에 :(콜론)과 ProtocolName을 적어줍니다.
상속과는 다르게 struct, enum도 채용이 가능합니다. 또한 여러 개의 protocol을 채용하는 것도 가능합니다.
예제에서는 두 개의 AProtocol, BProtocol을 정의했습니다. 그리고 stuct인 SomeStruct에서 이 두 가지 protocol을 한 번에 채용하도록 구현해보았습니다.
여기서 드는 의문은 그럼 Class라면?? 상속도 받고 protocol을 채용도 할 수 없을까??라는 의문이 들 수 있습니다.
Class의 경우도 한 번 구현해보도록 하겠습니다.
Class의 경우에는 상속을 받는다면 맨 처음에 SuperclassName이 먼저 와야 합니다.
그리고 그 이후에 여러 개의 protocol을 채택할 수 있습니다.
이렇게 Type들이 protocol을 어떻게 채용하는지 공부해보았습니다.
그럼 이제 각각 멤버들의 청사진을 어떻게 정의하는지 살펴보겠습니다!
Property
Protocol에서 프로퍼티의 청사진을 정의할 때는 var 키워드만 사용합니다.
그리고 stored 인지 computed인지 구분하지 않습니다. 오로지 이름과 타입 그리고 gettable인지 settable인지만 선언합니다.
var 키워드를 사용하면 무조건 settable이라고 생각할 수 있지만 protocol에서는 프로퍼티임을 나타내는 키워드일 뿐입니다.
Gettable과 Settable을 나누는 기준은 { get set } 으로 표시합니다.
위 예시는 프로퍼티 요구사항을 정의하는 방법을 구현한 것입니다.
모든 프로퍼티 요구사항은 var, name, type, { get, set } 으로만 정의합니다. 나머지는 명시할 필요가 없습니다.
Gettable은 { get } 으로 정의합니다. 여기서 주의할 점은 요구사항이 gettable로 정의되어있다고 Type에서 반드시 gettable로만 구현해야 한다는 것은 아닙니다. 즉 이 요구사항은 최소 요구조건입니다.
doesNotNeedToBeSettable이라는 이름과 같이 settable일 필요가 없는 것이지 반드시 gettable로 구현할 필요는 없다는 말입니다.
조금 설명이 어려울까요?? 다시 설명하자면 { get } 으로 정의되어있어도 protocol을 채용하는 Type에서는 settable로 구현해도 에러가 발생하지 않습니다.
Settable은 gettable을 포함하는 조건이니까요! 하지만 반대로 { get set } Settable로 정의되었는데 Type에서 gettable로 구현을 한다면 컴파일 에러가 발생합니다. settable 요구 조건을 충족하지 못했으니까요!
예제에서 아래 2개의 프로퍼티 요구사항은 잘못된 요구사항입니다.
var가 아닌 let을 사용하거나 { set } 만 사용하는 것은 틀린 문법입니다.
자세한 예시를 보도록 하겠습니다.
Figure라는 protocol을 정의했습니다. 그리고 String인 name이라는 gettable 프로퍼티를 정의했습니다.
Rectangle이란 struct는 요구사항대로 let을 사용하여 gettable stored property를 구현했습니다.
Triangle은 var를 이용해여 settable stored property를 구현했습니다. 위에서 설명했듯이 요구사항은 최소 요구사항이므로 gettable이지만 var로 선언해도 아무 문제가 없는 것을 확인할 수 있습니다.
마지막으로 Circle은 gettable computed property를 구현했습니다. 프로퍼티 요구사항은 stored, computed를 가리지 않습니다.
당연히 settable computed property도 가능합니다.
프로퍼티에는 instance property 말고 type property도 존재하죠??
Protocol에서는 type property도 정의 가능합니다.
문법은 var 앞에 static 키워드만 적어주면 됩니다.
class라면 class 키워드를 struct, enum이라면 static 키워드를 적는 게 아니라 모두 공통적으로 static 키워드를 적어주면 됩니다.
Method
Protocol에서는 instance method, type method 모두 정의할 수 있습니다.
일반적으로 우리가 Type에서 method 선언하듯이 선언하면 됩니다.
다만 구현은 protocol에서 하지 않으니 {}은 작성하지 않습니다. name, parameter, returnType 만 작성하면 됩니다.
아주 간단하죠??
그럼 이제 선언 가능한 method와 불가능한 method를 살펴보겠습니다.
Type method로 선언하고 싶다면 static을 사용하면 됩니다. 프로퍼티와 마찬가지로 채용하는 class에서 static대신 class로 구현해도 문제가 되지 않습니다.
그리고 파라미터를 보면 variadic 파라미터로 선언했습니다.
또한 value type에서는 method에서 인스턴스의 값을 변경한다면 mutating 키워드를 사용해야 했죠??
그럴 가능성이 있는 method라면 mutating을 붙여줍니다.
그리고 만약 class에서 이 메서드를 구현한다면 mutating을 붙이지 않고 선언할 수 있습니다.
이제 protocol에서 method를 정의하지 못하는 경우를 보겠습니다.
파라미터 기본값은 사용할 수 없습니다. 사용해보려고 했더니 default argument는 사용하지 못한다고 나오네요!
마지막으로 예제를 하나 보겠습니다.
Togglable 프로토콜을 선언했습니다. 그리고 mutating func인 toggle 메서드를 정의했죠.
toggle이란 것은 자신의 상태를 변경시킬 것으로 예상이 되니 mutating 키워드를 붙여줬습니다.
이제 Togglable을 채용하는 OnOffSwitch를 선언하고 toggle 메서드를 구현했습니다.
enum은 value type이고 toggle 메서드에서 off라면 on으로, on이라면 off로 자신의 상태를 변경하고 있으므로 mutating 키워드가 꼭 들어가야 합니다.
Initializer와 Subscript에 대해서도 한번에 작성하려 했지만 포스팅이 많이 길어져서 두 경우는 다음 포스팅에서 다루도록 하겠습니다!
참고자료
여러분의 새로운 도전을 응원합니다 | 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 as Type (0) 2021.12.29 Swift - Protocol Initializer , Subscript (0) 2021.12.28 Swift - Extension (0) 2021.12.20 Swift - Deinitializer (0) 2021.12.19 Swift - Required Initializer (0) 2021.12.18