본문 바로가기

개발/Swift

[Swift] Protocol

반응형

프로토콜 (Protocol)

프로토콜은 특정 작업이나 기능에 적합한 방법, 기타 요구사항을 정의한다.
간단하게 말하면 프로토콜은 어떠한 기능을 제공하기 위해 구성된 청사진이다.
프로토콜의 요건을 만들고 클래스(Class), 구조체(Structure), 열거(Enumeration)에서 채택되면
프로토콜에서 정의한 요구사항의 실제 구현을 진행할 수 있다.

 

프로토콜 구문 (Protocol Syntax)

간단한 프로토콜을 살펴보자.
프로토콜은 클래스와 구조체 형식과 매우 비슷한 형태로 선언한다.

protocol Rice {
	
}

프로토콜은 다중으로 채택될 수 있다. 

struct Lunch : Rice, Noodle {

}

class AmazingLunch : Lunch, Steak {

}

 

속성 요구사항 (Property Requirements)

프로토콜은 특정 이름과 유형을 가진 인스턴스를 제공하기 위해 준수 유형을 요구할 수 있다.
프로토콜은 속성이 저장된 속성이어야 하는지 혹은 계산된 속성이어야 하는지 지정하지 않는다. 
각 속성이 gettable 인지, gettable이어야 하며 settable 가능한지를 명시한다.
프로토콜에 set을 넣고 싶다면 get은 반드시 넣어야한다.

protocol Lunch {
    var howManyPeople : Int {get set}
    var money : Int { get }
}
protocol PhoneNumber {
    var number : String {get}
}

struct Person : PhoneNumber {
    var number : String
}

let customer = Person(number : "000-0000-0000")
// customer.number is "000-0000-0000"

 

 

Protocols — The Swift Programming Language (Swift 5.2)

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

 

여기 다양한 음료를 판매하는 커피숍이 있습니다.

enum Drink {
    case Coffee
    case MilkTea
    case Tea
    case Shake
}

class CoffeeShop {
    var menu : Drink
    var price : Float
}

 

폰으로 주문할 수 있는 프로토콜을 만들어 보았습니다.

protocol phoneCall {
    func order(menu: String, price: Float)
}

 

프로토콜 선언 방식은 여러가지 입니다. 
하나는 extension을 이용해 프로토콜을 정의하는 방법,
클래스와 구조체에서 protocol을 채택해 해당 클래스와 구조체에서 프로토콜을 정의하는 방법입니다.

extension phoneCall {
    func order(menu: String, price: Float) {
    	print("주문하신 메뉴인 \(menu)의 가격은 \(price)원입니다.")
    }
}

 

예) 구조체에서 프로토콜을 채택해 정의하는 방식 

struct CoffeeShopStruct : phoneCall{
    var selectMenu: Drink?
    
    func order(menu: Drink, many: Int) {
        let total = menu.rawValue * many
        print("1번 상점 : 주문하신 메뉴인 \(menu)를 \(many)개 주문하셨습니다.\n총 금액은 \(total)원입니다.")
    }
}

 

예) 클래스로 프로토콜을 채택해 정의하는 방식

class CoffeeShopClass : phoneCall{
    var menu : Drink?
    
    func order(menu: Drink, many: Int) {
        let total = menu.rawValue * many + 1000
        print("2번 상점 : 주문하신 메뉴인 \(menu)를 \(many)개 주문하셨습니다.\n총 금액은 \(total)원입니다.")
    }
}

 

 


 

Associatedtype 

 

associatedtype는 하나 이상 프로토콜에 관련있는 타입에 이름을 지정한다. 
타입 T인 name 은 하나 이상의 프로토콜을 따르므로, 프로토콜에 정의된 변수 또는 함수를 사용할 수 있다.

protocol B {}
protocol C {}

extension B {
    var description : String {
        return "Hi"
    }
}

extension C {
    var bug : String {
        return "Bug"
    }
}

protocol A {
    associatedtype T : B, C
    var name : T {get set}
}

extension A {
    mutationg func set(name : T) {
        self.name = name
    }
    
    var description : String {
        return name.description
    }
    
    var bug : String {
        return name.bug
    }
}
}

associatedtype을 잘 이용하면 Protocol Extension에서 거의 모든 것을 만들고, 해당 프로토콜을 따르기만 하는 타입을 선언하면 된다.

http://minsone.github.io/swift3-protocol-extension-associatedtype

반응형

'개발 > Swift' 카테고리의 다른 글

[Swift] NSAttributedString  (0) 2021.02.25
[Swift] 문자열 색인  (0) 2021.02.25
[Swift] Protocol 알아보기  (0) 2021.02.25
[Swift] 프로토콜 지향 프로그래밍  (0) 2020.08.13
[Swift] Typealias  (0) 2020.03.12