반응형
LinkedIn 개발자로 성장하면서 남긴 발자취들을 확인하실 수 있습니다.
Github WWDC Student Challenge 및 Cherish, Tiramisul 등 개발한 앱들의 코드를 확인하실 수 있습니다.
개인 앱 : Cherish 내 마음을 들여다보는 시간, 체리시는 디자이너와 PM과 함께 진행 중인 1인 개발 프로젝트입니다.
10년 후, 20년 후 나는 어떤 스토리 텔러가 되어 있을지 궁금하다. 내가 만약에 아직 조금 더 탐구하고 싶은 게 있고, 궁금한 게 있다면, 그게 설사 지금 당장의 내 인생에 도움이 안 되는 것 같더라도 경험해보자. 그 경험들을 온전히 즐기며 내 것으로 만들고, 내 일에 녹여내고... 그러다보면 그 점들이 모여 나란 사람을 그려내는 선이 될 테니까.

Recent Posts
Recent Comments
Total
관리 메뉴

꿈꾸는리버리

protocol 정복기 ( 3 / 3) 본문

오뚝이 개발자/swift

protocol 정복기 ( 3 / 3)

rriver2 2022. 7. 24. 10:19
반응형

이전포스팅에서 protocol에서 method나 init을 요구할 때에 대해 알아봤다.

이번 포스팅에서는 프로토콜을 상속하는 경우, class 전용 프로토콜, 그리고 프로토콜의 조합과 프로토콜을 준수했는지 확인하는 등...의 프로토콜의 또 다른 부분을 다뤄보고자 한다. 

 

🌷 protocol의 상속 

protocol은 하나 이상의 protocol을 상속 받아 기존 protocol의 요구사항보다 더 많은 요구사항을 추가할 수 있다. 클래스의 상속 문법과 유사하기 때문에 크게 어렵지는 않다 !

protocol FirstProtocol {
    var name: String { get }
}

protocol FirstProtocol2 {
    var height: Int { get }
}

protocol SecondProtocol: FirstProtocol, FirstProtocol2 {
    var age: Int { get }
}

class someClass: SecondProtocol {
    var name: String
    var height: Int
    var age: Int
    init() {
        self.name = "River"
        self.height = 200
        self.age = 200
    }
}

이렇게 FirstProtocol과 FirstProtocol2를 상속 받은 SecondProtocol이 있고, someClass는 SecondProtocol을 따르기 때문에 3개의 protocol에서 요구하는 사항을 모두 준수해야 한다.

 

🌷 클래스 전용 protocol 

이렇게 protocol의 상속 리스트에 AnyObject 키워드를 추가하면 프로토콜이 클래스 타입에만 채택될 수 있도록 제한할 수 있다. (프로토콜의 상속 리스트 중 맨 처음에 위치해야 함)

protocol SomeProtocol: AnyObject {
    var name: String { get }
}

class someClass: SomeProtocol {
    var name: String
    init() {
        self.name = "River"
    }
}

기존에는 AnyObject 대신에 class를 적었었는데 Swift 4 이후로는 AnyObject를 작성한다고 한다. (참고)

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

 

🌷 protocol 조합 

하나의 매개변수가 여러 프로토콜을 준수하는 타입이어야 한다면, & 을 사용해서 하나의 매개변수에 여러 프로토콜을 한번에 조합하여 요구할 수 있다. 

protocol SomeProtocol: AnyObject {
    var name: String { get }
}
protocol SomeProtocol2: AnyObject {
    var age: Int { get }
}

func someFunc(parameter: SomeProtocol & SomeProtocol2) {
    // do something
}

 

이와 함께 특정 클래스의 인스턴스 역할을 할 수 있는지도 함께 확인할 수 있는데, 조합 중에 클래스는 한 타입만 조합할 수 있다. ( struct와 enum은 불가 )

class someClass {
    var name: String = ""
    var age: Int = 0
}

func someFunc(parameter: SomeProtocol & SomeProtocol2 & someClass) {
    // do something
}

 

🌷 protocol 준수 확인 

is 연산자를 통해 해당 인스턴스가 특정 프로토콜을 준수하는지 확인할 수 있다.

protocol SomeProtocol {
    var name: String { get }
}
protocol SomeProtocol2 {
    var age: Int { get }
}

class SomeClass: SomeProtocol, SomeProtocol2 {
    var name: String = ""
    var age: Int = 0
}

let someclass: SomeClass = SomeClass()
print(someclass is SomeProtocol)

as? 다운 캐스팅 연산자를 통해 다른 프로토콜로 다운캐스팅을 시도해볼 수 있다.

protocol SomeProtocol {
    var name: String { get }
}
protocol SomeProtocol2 {
    var age: Int { get }
}

class SomeClass: SomeProtocol, SomeProtocol2 {
    var name: String = ""
    var age: Int = 0
}
let someclass: SomeClass = SomeClass()
if let someProtocol2: SomeProtocol2 = someclass as? SomeProtocol2 {
    print("\(someProtocol2) is SomeProtocol2")
}

 

요론거는 언제 쓰나면,,

이렇게 someClass는 SomProtocol의 타입이기 때문에 someProtocol의 요구 method와 property만 사용할 수 있지만,

다운 캐스팅을 하면 인스턴스 자체의 method와 property를 사용할 수 있다.

 

  protocol의 장점  

 

자세한 Type을 숨길 수 있다! student인지, teacher인지에 상관 없이 person이기만 하면 되는 것처럼 개발자는 구체적인 Type에 일일히 대응하거나 특정 구조체(Type)를 return하는 경우들 하나하나에 연연하지 않을 수 있다. 이렇게 Protocol에 호환되도록 하고, 그 Protocol에 맞춰서 코드를 작성한다면 protocol을 위반하지 않는 선에서 특정 구조체 내부에 변화가 있더라도 모든 코드의 의존성이 깨질까 걱정하지 않아도 된다! 이런 이유 때문에 Test를 할 때 protocol을 사용하게 된다.

또, Protocol은 Type이기 때문에 활용할 수 있는 범위가 넓다. 함수의 매개변수로 사용되기도 하고, 리턴값으로 사용되기도 하는 등 활용할 수 있는 가능성이 매우 높다.

마지막으로는 class와 달리 다중 상속이 가능하다는 점이다!  한 Protocol이 다른 Protocol을 여러개 채택할 수도 있고, 한 구조체나 클래스가 많은 Protocol을 채택할 수 있기 때문에 활용도가 높다.

 

  참조  

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

 

Protocols — The Swift Programming Language (Swift 5.7)

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

반응형
Comments