Swift - Protocol(1_선언, 옵셔널)

이한솔·2023년 9월 18일
0

Swift 문법 🍎

목록 보기
24/32

Protocol

어떤 기능에 적합한 특정 메서드, 프로퍼티 및 기타 요구 사항의 청사진Blueprint를 의미한다.
클래스, 구조체, 열거형이 프로토콜을 채택할 수 있고, 프로토콜에 정의된 요구사항의 실제 구현을 제공해야한다.
프로토콜의 요구 사항을 모두 충족하면 해당 프로토콜에 부합하다고 한다.

프로퍼티 선언

  1. 프로토콜에 선언되는 프로퍼티는 항상 var로 선언 되어야 한다.
  2. 프로토콜을 채택해서 선언된 프로퍼티를 구현할 때, 저장 프로퍼티나 연산 프로퍼티로 모두 구현할 수 있다
// 프로토콜 정의
// 프로퍼티를 선언하여 값을 직접 정의하고, 메서드를 직접 구현 하는 것이 아니라 
// 해당 프로토콜을 채택하려면 정해진 속성과 메소드를 무조건 갖고있어야한다는 약속을 정의해두는 것
protocol AProtocol {
    var name: String { get }
}


// 프로토콜 채택 방법
// 채택할 프로토콜 이름을 쉼표`,`로 구분하여 명시
struct AStruct: AProtocol, BProtocol {
   // var name: String 프로퍼티를 무조건 갖고있어야함
}

// 상속받는 클래스의 프로토콜 채택
// SubClass의 경우 SuperClass를 가장 앞에 명시한다.
class AClass: SuperClass, AProtocol {

}


// 프로토콜 프로퍼티는 무조건 var로 선언되어야함
protocol Person {
    var name: String  { get }
}

// 저장프로퍼티, 연산프로퍼티 둘 다 정의 가능하다.
// 저장 프로퍼티로 정의
class ABand: Person {
    var name: String = "hansol"    
}
 
// 연산 프로퍼티로 정의
class BBand: Person {
    var name: String {
        get { 
            return "hansol"        
        }     
    }
}
  1. 프로퍼티가 { get } 일 때
    저장 프로퍼티: let / var 둘 다 가능
    연산 프로퍼티: get(get-only) / get & set 둘 다 가능
protocol AProtocol {
    var age: Int { get }
}

// 저장 프로퍼티 let / var 둘 다 가능
class AClass: AProtocol {
    var age: Int = 19
}

// 연산 프로퍼티 get / get & set 가능
class BClass: AProtocol {
    var a: Int = 1
    var age: Int {
        get {
            return 19
        }
        set {
            self.a = newValue
        }
    }
}
  1. 프로퍼티가 { get set } 일 때
    저장 프로퍼티: var로만 선언 가능
    연산 프로퍼티: get & set로만 선언 가능

메서드 선언

  1. 함수의 헤더 부분만 프로토콜에 작성, 바디는 해당 프로토콜을 채택하는 곳에서 구현한다.
protocol Person {
    func speak() // 함수의 헤더부분만 작성
}

class AClass: Person {
    func speak() {
        print("can speak") // 함수의 바디부분 작성
    }
}

let p = AClass()
p.speak() // 출력값: can speak
  1. 구조체 mutating 키워드 사용 시 프로토콜 자체에 추가한다.
protocol Person {
    mutating func changeName(changeName: String)
}

struct AStruct: Person {
    var name: String = "hansol"
    
    mutating func changeName(changeName: String) {
        self.name = changeName
    }
}


Protocol Optional

프로토콜에 @objc 선언 후 프로퍼티 앞에 @objc optional을 붙일 경우 해당 프로퍼티는 필수가 아닌 optional로 바뀐다.
채택해주는 곳에서 꼭 선언해주지 않아도 된다. 하지만 @objc라는 문법을 사용하면 구조체에서는 채택하지 못하고 클래스에서만 채택할 수 있다.

@objc protocol AProtocol {

    var name: String { get }
    @objc optional var age: Int { get }
}

class SomeClass: AProtocol {
    var name: String = ""
    var age: NSNumber? = 19
}


let a = SomeClass()
print(a.name) // 출력값: sol
print(a.age) // 출력값: Optional(19)

0개의 댓글