BOID

[swift] 프로토콜(protocol)에대해 파해치기 (1 / 2) - HoonIOS 본문

swift 시작기

[swift] 프로토콜(protocol)에대해 파해치기 (1 / 2) - HoonIOS

HoonIOS 2021. 4. 28. 10:45

안녕하세요 HoonIOS입니다. :)

 

델리게이트에 대해 다시 공부하던 중 델리게이트 메서드 앞에 optional이라는 프로토콜에서 선택적 요구사항에 대해 다시 공부를 하던 중 프로토콜을 한번 전체적으로 포스팅하는 게 나쁘지 않겠다고 생각을 프로토콜에 대해 포스팅을 하려고 합니다 ㅎㅎ

 

 

프로토콜은 스위프트 언어 안에서 매우 강력한 기능입니다. 스위프트를 처음 발표를 했을때 애플에서 스위프트는 프로토콜 지향 프로그래밍 언어라고 발표를 했죠  

 

그럼 프로토콜이란 무엇일까요?

 

 프로토콜이란?

 

프로토콜은 특정 역할을 수행 하기 위한 메서드, 프로퍼티, 이니셜 라이저 등을 청사진으로 정의한 것으로 하나의 밑그림을 그린 것으로 생각을 하시면 됩니다.

 

어떤 프로토콜의 요구사항을 따르는 타입은 해당 프로토콜을 준사한다고 나타낸다고 합니다.

 

프로토콜의 문법적 요소중 제일 중요한것은 프로토콜은 정의만 제시할 뿐이지 안에 있는 코드를 작성하지는 않는다. 는 것입니다. 

(이게 무슨 말이야...ㅠㅠ 하실 수 있으시겠지만 뒤에 예시를 보다 보시면 아 이런 내용이구나 하실 거예요 실망은 아직 이릅니다.!)

 

그럼 프로토콜의 문법을 한번 보실까요?

 

 프로토콜 문법

 

protocol 프로토콜 이름 {

	프로토콜 정의
    
}

 

클래스 열거형 구조체에서 프로토콜을 채택을 하려면 뒤에 클론을 붙여서 채택할 프로토콜 이름을 쓰고 쉼표로 구분해주면 됩니다.

 

 

 

* 코드 설명

  • 위에 코드를 보시면 샘플 프로토콜 2개를 명시해주고 각 구조체, 클래스, 열거형에 프로토콜을 명시해준것을 볼 수 있습니다.
  • 구조체, 클래스 열거형, 프로토콜 모두에서 사용이 가능합니다.

 

만약 클래스를 상속하고 프로토콜을 구현해주려면 프로토콜을 먼저 상속하고 그다음 쉼표를 구현후 프로토콜을 나열해주면 됩니다.

 

 

 

 

 프로토콜의 요구사항

 

프로토콜은 자식을 채택한 타입이 어떤 프로퍼티를 구현해야 하는지 요구를 할 수 있습니다.

대신에 프로토콜은 저장, 연산 프로퍼티의 종류는 따로 신경을 쓰지 않습니다.

 

프로토콜에 채택한 타입은 이름과 타입만 맞도록 구현해주면 됩니다.

 

다만 프로퍼티를 프로토콜에 정의를 하면  var키워드를 통해 정의를 해줘야 하고 읽기 전용으로 할지 읽기 쓰기 전용으로 할지는 프로토콜이 정해야 합니다. 

예를 들어서 읽기 쓰기가 모두 가능한 프로퍼티는 { get set }으로 정의를 해주고 읽기 전용 프로퍼티로 정의하려면 { get }으로 명시를 해주면 됩니다.

 

클래래스의 타입 프로퍼티에는 상속 가능한 타입 프로퍼티인 calss 타입 프로퍼티상속 불가능한 static타입 프로퍼티가 있지만 둘의 프로퍼티를 구분할 때는 static만 앞에 키워드를 붙여서 구분해 부면 됩니다.

 

 

 

이제 예시를 들어보겠습니다.

 

 

 

* 코드 설명

  • sample 프로토콜에 sample 읽기 쓰기 가능한 sample 변수와 읽기만 가능한 sample2 변수를 구현해줬습니다.

 

 프로토콜에서 메서드 요구

 

프로토콜에서는 인스턴스 메서드, 타입 메서드 둘다 요구를 할 수 있습니다.

 

이것을 정의할 때는 코드값이 들어가는  { } ( 중괄호 ) 부분을 제외하고는 메서드 이름, 매개변수, 반환 타입만 구현을 해주면 됩니다. 아아 가변 매개변수도 허용합니다 ㅎㅎ

 

타입 메서드를 우선 설명해보면 타입 프로퍼티와 마찬가지로 앞에 static을 붙여주면 됩니다. 그러나 타입 메서드를 클래스에서 구현할 때는 static, class 어느 것을 구현해줘도 무방합니다.

 

즉 다시 말해서 static을 구현해줘도 실제 클래스에 구현을 할 때에는 class로 구현할지 static 타입 메서드로 구현을 할지는 클래스의 특성에 따라 다시 골라서 사용해주면 됩니다.

 

그냥 말로만 설명하면은 모르니 한번 예시를 통해 살펴보겠습니다.

 

 

 

* 코드 설명

  • people프로토콜에는 me, you 변수를 읽기 전용으로 구현을 해줬고 Hello 프로토콜, goodBye 프로토콜에는 함수를 구현해줬습니다. 
  • 각 프로토콜을 Friend 클래스에 구현을 해주고 메서드를 보면 함수명 매개변수를 프로토콜에 그대로 구현을 해줬으므로 코드만 작성을 해줬습니다.
  • 따라서 인스턴스를 생성 후 메서드를 실행하면 아래 print값이 출력되는 것을 되는것을 확인할 수 있습니다.

 

이제는 값 타입에서 내부에서 인스턴스 메서드로 인해 해당 인스턴스 내부의 값을 변경하게 될 때 사용하는 프로토콜 요구사항을 한번 살펴보겠습니다.

 

 값 타입의 가변 메서드 요구 사항

 

값 타입의 인스턴스 메서드는 자기 자신의 인스턴스에 있는 내부의 값을 변경하려고 할 때 메서드의 func 키워드 앞에 mutating 키워드를 적어 내부의 값을 바꿔요~라고 알려줍니다. 

 

구조체에서 메서드를 이용해 내부의 값을 바꿀 때 앞에 mutating키워드를 사용하는 것과 마찬가지입니다.

 

참조 타입에는 필요가 없지만 값 타입에서는 무조건 내부의 인스턴스를 변경하는 메서드가 있으면 mutating키워드를 적어줘야 합니다.

 

 

 

* 코드 설명

  • makeZero, makeFull 프로토콜을 정의해주고 함수 앞에는 mutating키워드를 정의해 줌으로써 구조체에서 내부의 값을 변경해도 사용할 수 있는 메서드로 만들었습니다.
  • player 클래스를 보면 프로토콜에서 선언해준 메서드를 mutating키워드 없이 내부의 변숫값들을 바꿀 수 있는 것을 볼 수 있습니다.
  • player2 구조체를 보면 프로토콜에서 선언해준 메서드에 mutating키워드를 사용하여 내부의 변수값들을 바꿀수 있는것을 볼수 있습니다.
  • 이렇게 두 개의 클래스 구조체를 비교해 보면 클래스는 제약 없이 내부의 값을 바꿀수 있지만 구조체는 내부의 값을 바꿀려면 제약이 생기게 됩니다.
  • 만약 위 두개의 프로토콜에서 가변 메서드(mutating)를 요구하지 않았으면 값 타입에서 인스턴스 내부의 값을 바꾸는 메서드를 구현할 수 없습니다.

 

한 번에 포스팅하려고 했는데 프로토콜 개념들이 너무 많네요.... 우선 다음 2편으로 가서 포스팅을 하겠습니다.

boidevelop.tistory.com/77

[swift] 프로토콜(protocol)에 파해치기 (2 / 2) - HoonIOS

안녕하세요 HoonIOS입니다. 저번에 프로토콜에 대해 포스팅을 했는데요 한 페이지에 하면 양도 너무 많아서 두 개로 나눴습니다. 이번 포스팅에서는 이니셜라이저 상속, 여러 프로토콜의 상속, 매

boidevelop.tistory.com

 

반응형
Comments