본문 바로가기

Swift

Swift - Protocols Property 요구사항

벌써 제가 2번째 글을 쓰고 있네요 ㅎㅎ

처음에 글 쓸 때만 해도 이거를 내가 쓸 수 있을까 싶었는데

그래도 한번 글을 쓰고 나니깐 2번째 글 쓰는 거는 상대적으로 더 쉽게 느껴지네요 :)


저번에는 프로토콜의 기본 개념에 대해서 알아봤었는데

전에 글을 못읽으신 분들을 위해서 이 글 제일 밑에 링크를 남겨 놓을게요

굳이 읽지 않아도 상관없지만 이전 글을 읽고 오시면

이번 글을 이해하는데 더 도움이 되지 않을까 싶네요!


이번에 공부할 내용은 프로토콜의 프로퍼티 요구사항에 대해서 알아볼려고 해요

애플 공식 문서에 있는 글을 확인해보면

"프로토콜은 특정한 이름과 타입과 함께 인스턴스 프로퍼티 또는 타입 프로퍼티를 제공하기 위해 준수해야 하는 타입을 요구할 수 있다"

처음 글에서도 얘기 했지만 프로토콜은 청사진과 같기 때문에 자세한 내용은 없고 틀만 잡아주는 역할을 해요

그래서 프로토콜에서는 프로퍼티를 선언하기위한 틀만 잡아준다 라고 생각하시면 될 것 같아요

 

그리고 이제 그 틀의 모양에 대해서 알아보도록 할게요!!

  1. 프로토콜에서 프로퍼티는 무조건 var를 이용해서 선언해야 합니다
  2. 프로퍼티의 이름과 타입만 명시하면 된다
  3. 이 프로퍼티가 gettable인지 gettable/settable 둘 다 인지 명시해야 한다
  4. 타입 프로퍼티를 선언하는 경우 var 앞에 static 키워드만을 무조건 사용해야 한다(class 키워드는 안됨!!)

위에 4가지가 프로퍼티를 선언할 때 프로토콜에서 제시한 틀의 모양이에요

우리는 저 모양에 맞게 프로퍼티를 선언해 주면 끝이에요!!

생각보다 별거 없죠 ㅎㅎ

 

별거 없어 보여도 글로 보는 거랑 예제로 보는 거랑 또 다르니깐 한번 예제를 보도록 할까요?

protocol SomeProtocol {
    
    var mustBeSettable : Int {get set}
    
    var doesNotNeedToBeSettable : Int {get}
    
}
protocol AnotherProtocol {
    
    static var someTypeProperty : Int {get set} // {get}만 사용해도 상관없음!
    
}

위에 2개의 예제는 아까 설명드렸던 프로퍼티를 선언하는 방법을 적용해서 선언한 프로퍼티인데요

처음은 var로 선언하시고 프로퍼티 이름, 타입, {get or get/set} 순으로 작성해주시면 되고

타입 프로퍼티 같은 경우는 var 앞에 static이라는 키워드만 붙여주시면 됩니다 :)

 

그럼 이제 프로퍼티를 정의하는 법을 배웠으니 구현하는 방법도 한번 알아보도록 할까요??

protocol FullyNamed {
    
    var fullname : String {get}
    
}

먼저 하나의 인스턴스 프로퍼티를 가지는 프로토콜을 하나 선언하도록 할게요~

struct Person : FullyNamed {
    
    // Type 'Person' does not conform to protocol 'FullyNamed'
    
}

그다음 구조체를 하나 선언해 준 다음 FullyNamed라는 프로토콜을 적용하였더니

"Type 'Person' does not conform to protocol 'FullyNamed'"라는 오류가 발생하게 되네요

그 이유는 구조체나 클래스나 열거형에서 어떤 프로토콜을 채택하였는데

그 프로토콜에 정의되어있는 형태를 준수하지 않은 경우에 발생하는 에러예요

struct Person : FullyNamed {
    
    var fullname : String
    
}

그런 경우에는 위에 있는 코드처럼 FullyNamed 프로토콜에서 정의한 프로퍼티를 작성해 주시면 됩니다

여기에서는 저장 프로퍼티로 선언이 되었네요

(이거는 선택이 아니라 필수입니다!!!)

 

이번에는 정의 방식에 따른 프로퍼티 구현 방법에 대해서 알려드리도록 할게요

일단 위에서 보셨던 프로토콜을 한번 더 선언하도록 할게요

protocol FullyNamed {
    
    var fullname : String {get}
    
}

위에 나와있는 코드에서 프로퍼티는 {get} 형식으로 선언이 되어있는 것을 보실 수 있을 텐데요

이런 경우에는 구현부에서 어떤 인스턴스 프로퍼티든지 선언하실 수 있어요

 

직접 코드로 한번 구현해보도록 할까요?

struct Person : FullyNamed {
    
    var fullname : String
    
}

위에 코드는 변수 저장 프로퍼티를 구현한 것이고

struct Person : FullyNamed {
    
    let fullname : String
    
}

위에 코드는 상수 저장 프로퍼티를 구현한 것이고

struct Person : FullyNamed {
    
    var name : String
    
    var fullname : String {
        
        return "my name is \(name)"
        
    }
    
}

위에 코드는 연산 프로퍼티 읽기 전용으로 구현한 것이고

struct Person : FullyNamed {
    
    var name : String
    
    var fullname : String {
        get{
            
            return "my name is \(name)"
        }set(newName) {
            
            name = newName
        }
    }
    
}

위에 코드는 연산 프로퍼티 읽기 쓰기 전용으로 구현한 것이에요

여기서 알아둬야 할 것은 위에 프로토콜처럼 {get}으로 정의한 경우에는 4가지의 인스턴스 프로퍼티가 될 수 있지만

연산 프로퍼티에서 읽기 쓰기 전용 같은 경우에는 진짜 필요하면 사용할 수는 있는데 그렇게 권장하는 느낌은 아니더라고요 ㅎ

 

 

이번에는 {get set}인 경우를 보도록 할까요?

protocol FullyNamed {
    
    var fullname : String {get set}
    
}

아까랑 비슷해 보이지만 이번 코드는 {get set}으로 선언되어 있는 것을 보실 수 있을 거예요

이런 경우에는 인스턴스 프로퍼티 종류에서 2가지만 피하시면 됩니다

  1. 상수 저장 프로퍼티
  2. 연산 프로퍼티 (읽기 전용)

보시면 아시겠지만 선언을 했을 경우 수정이 불가능한 프로퍼티는

프로토콜이 {get set}으로 선언되어 있는 경우 구현부에서 작성이 불가능하다는 것!! 명심해 주세요!!

선언하는 방법은 {get}과 동일하기 때문에 예제는 넘어가도록 할게요 ㅎ


이때까지 공부한 프로퍼티는 인스턴스 프로퍼티에 관한 내용이었고

애플 문서에서도 딱히 언급은 없지만 타입 프로퍼티에 대해서 잠깐 언급을 하고 지나가려고 해요

위에 예제를 보시면 프로토콜에서 프로퍼티 정의하는 법을 할 때 잠깐 보셨을 텐데

 

타입 프로퍼티 구현하는 방법에 대해서 한번 알아보도록 할게요

protocol SomeProtocol {
    
    static var someTypeProperty : Int {get} // {get set}으로 선언 가능!
    
}

일단 타입 프로퍼티를 가지는 프로토콜을 하나를 위에처럼 선언하도록 할게요

struct SomeStruct : SomeProtocol {
    
    static var someTypeProperty: Int = 6
    
}

위에 코드는 변수 저장 타입 프로퍼티이고

struct SomeStruct : SomeProtocol {
    
    static let someTypeProperty: Int = 6
    
}

위에 코드는 상수 저장 타입 프로퍼티이고

var num : Int = 3

struct SomeStruct : SomeProtocol {
    
    static var someTypeProperty: Int {
        
        return num
    }
    
}

위에 코드는 연산 타입 프로퍼티 (읽기 전용)이고

var num : Int = 3

struct SomeStruct : SomeProtocol {
    
    static var someTypeProperty: Int {
        get{
            return num
        }set{
            num = newValue
        }
    }
}

위에 코드는 연산 타입 프로퍼티 (읽기 쓰기 전용)이에요

var num : Int = 3

class SomeClass : SomeProtocol {
    
    class var someTypeProperty: Int {
        
        return num
    }
    
}

클래스인 경우에는 프로토콜에서는 static 키워드로 정의가 되어 있어도

class 키워드로도 선언이 가능해서 상속했을 경우 오버 라이딩할 수 있도록 구현할 수도 있어요!!

var num1 : Int = 4

class SomeSubClass :SomeClass {
    
    override static var someTypeProperty: Int {
        
        return num1
    }
    
}

이렇게 말이죠 ㅎ

 

인스턴스 프로퍼티 선언하는 것과 크게 다른 것이 없죠?

그냥 static 키워드만 앞에 선언해주시면 됩니다 :)

 

여기까지가 프로퍼티 요구사항에 대한 글을 마치게 되었습니다!!

부족한 부분이 보이시거나 틀린 부분이 있다면 알려주시면 감사드리겠습니다~


 

이번 글은 내용이 좀 있다 보니깐 글이 길어졌네요....

부족한 글 솜씨와 내용이었지만 여기까지 읽어주셔서 감사합니다!!

다음에는 프로토콜 메서드 요구사항에 대한 글로 돌아오도록 할게요

 

요즘 코로나19도 심하고 한데 다들 건강 조심하세요 :)

 

Swift - Protocols 기본개념

이번에 처음으로 블로그를 만들어서 글을 작성하게 되었네요 ㅎ swift언어 공부를 시작한 지는 꽤 지났는데 시간이 지날수록 까먹더라고요 사람에 머리에 한계가 있어서 그런지... 그래서 이번에 제가 블로그를 만..

peachberry0318.tistory.com

'Swift' 카테고리의 다른 글

Swift - Properties - Property Wrappers  (0) 2020.07.21
Closure - Capture List  (0) 2020.07.17
Swift - Protocols Method 요구사항  (0) 2020.03.12
Swift - Protocols 기본개념  (0) 2020.03.07