ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • swift - Protocols #6 (Protocol Types, protocol Conformance, Collection of protocol Types)
    swift 2021. 1. 12. 19:02

    Protocol Types

     

    프로토콜은 First-class Citizen이다. 다시 말해서 독립적인 형식

     

    변수와 상수를 선언할때 자료형으로 사용하거나 파라미터의 자료형, 리턴형의 자료형으로 사용하는 것도 가능함

     

    protocol Resettable {
       func reset()
    }
    
    class Size: Resettable {
       var width = 0.0
       var height = 0.0
       
       func reset() {
          width = 0.0
          height = 0.0
       }
    }
    
    let s = Size()
    
    // upcating과 유사
    // 프로토콜로 저장하면 프로토콜에 저장된 멤버만 사용 가능
    let r: Resettable = Size()
    // r.width  err
    // r.height  err
    
    r.reset() // 호출가능

    프로토콜 적합성

    // 프로토콜 적합성 : 특정형식이 프로토콜을 채용하고있는지를 나타내는 척도
    // type Casting 연산자를 이용해서 확인한다.
    
    
    protocol Resettable {
       func reset()
    }
    
    class Size: Resettable {
       var width = 0.0
       var height = 0.0
       
       func reset() {
          width = 0.0
          height = 0.0
       }
    }
    
    let s = Size()
    
    
    // is 연산자
    s is Resettable // true
    s is ExpressibleByNilLiteral // false
    
    // as 연산자
    // 인스턴스를 프로토콜 형식으로 캐스팅하거나 프로토콜형식으로 저장된 인스턴스를 실제 형식으로 캐스팅할때 사용
    let r = Size() as Resettable
    // 원래 형식으로 casting할때는 compile time casting은 사용할 수 없다.
    r as? Size

    Collection of protocol Types

    protocol Figure {
       func draw()
    }
    
    struct Triangle: Figure {
       func draw() {
          print("draw triangle")
       }
    }
    
    class Rectangle: Figure {
       func draw() {
          print("draw rect")
       }
    }
    
    struct Circle: Figure {
       var radius = 0.0
    
       func draw() {
          print("draw circle")
       }
    }
    
    let t = Triangle()
    let r = Rectangle()
    let c = Circle()
    
    // 같은 superclass를 상속받으면 upcasting이 자동으로 되지만 그것도 아니고
    // t, r, c가 값 형식과 참조형식이 섞여 있기 때문에 upcasting에 실패하고 에러가 발생
    // let list = [t, r, c]
    
    // 하지만 모두 같으 protocol을 채용중 -> 프로토콜은 자료형으로 사용이 가능하다
    // 인스턴스가 값인지 참조인지 상관하지 않고 가능
    let list: [Figure] = [t, r, c]
    
    for item in list {
        // item은 Figure 타입이기 때문에 프로토콜에 선언되어있는 draw만 사용가능
        item.draw()
        
        // downcasting을 통해서 가능
        if let c = item as? Circle {
            c.radius
        }
    }

    댓글

Designed by Tistory.