주니곰의 괴발노트
Swift - Protocol(메서드, 초기화) (2/4) 본문
메서드 요구사항
- 프로토콜은 준수하는 타입에 의해 구현되기 위해 지정한 인스턴스 메서드와 타입 메서드를 요구할 수 있음
- 프로토콜에서 정의하는 메서드는 일반적인 인스턴스와 타입 메서드와 같은 방식으로 명시적으로 프로토콜의 정의의 부분으로 작성되며 중괄호가 없거나 메서드 바디가 없음
- 일반적인 메서드와 같은 규칙에 따라 가변 파라미터는 허용되나 기본 값은 프로토콜의 정의 내에서 메서드 파라미터에 대해 지정될 수 없음
- 타입 프로퍼티 요구사항과 마찬가지로 프로토콜에 정의될 때 static 키워드를 항상 타입 메서드 요구사항 앞에 표기
- 클래스에 의해 구현될 때 타입 메서드 요구사항에 class 또는 static 키워드가 접두사로 붙는 경우에도 마찬가지
protocol SomeProtocol {
static func someTypeMethod()
}
protocol RandomNumberGenerator {
func random() -> Double
}
class LinearCongruentialGenerator: RandomNumberGenerator {
var lastRandom = 42.0
let m = 139968.0
let a = 3877.0
let c = 29573.0
func random() -> Double {
lastRandom = ((lastRandom * a + c)
.truncatingRemainder(dividingBy:m))
return lastRandom / m
}
}
let generator = LinearCongruentialGenerator()
print("Here's a random number: \(generator.random())")
// Prints "Here's a random number: 0.3746499199817101"
print("And another one: \(generator.random())")
// Prints "And another one: 0.729023776863283"
- RandomNumberGenerator 프로토콜은 호출될 때마다 Double 값을 반환하는 random 이라는 인스턴스 메서드를 요구
- 프로토콜 부분으로 지정되지 않았지만 이 값은 0.0 부터 1.0 미만의 숫자라고 가정
- RandomNumberGenerator 프로토콜은 각 난수가 생성되는 방법에 대해 어떠한 것도 가정하지 않음
- 단순히 생성기가 새로운 난수를 생성하는 표준 방법을 제공하면 됨
메서드 요구사항 변경
- 값 타입 (구조체와 열거형)에 대한 인스턴스 메서드의 경우 메서드의 func 키워드 앞에 mutating 키워드를 위치시켜 메서드가 속한 인스턴스와 인스턴스의 모든 프로퍼티를 수정할 수 있음을 나타냄
- 프로토콜을 채택하는 모든 타입의 인스턴스를 변경하기 위한 프로토콜 인스턴스 메서드 요구사항을 정의하는 경우 프로토콜의 정의의 부분으로 mutating 키워드로 메서드를 표시
- mutating 키워드는 구조체와 열거형에 의해서만 사용되므로 클래스에 대한 해당 메서드의 구현을 작성할 때 mutating 키워드를 작성할 필요가 없음
protocol Togglable {
mutating func toggle()
}
enum OnOffSwitch: Togglable {
case off, on
mutating func toggle() {
switch self {
case .off:
self = .on
case .on:
self = .off
}
}
}
var lightSwitch = OnOffSwitch.off
lightSwitch.toggle()
// lightSwitch is now equal to .on
- toggle 이라는 단일 인스턴스 메서드 요구사항을 정의하는 Togglable 이라는 프로토콜을 정의
- toggle() 메서드는 해당 타입의 프로퍼티를 수정하여 모든 준수하는 타입의 상태를 전환하거나 반전하기 위한 것
- toggle() 메서드는 호출될 때 준수하는 인스턴스의 상태를 변경하기 위한 메서드를 나타내기 위해 Togglable 프로토콜 정의의 부분으로 mutating 키워드로 표시
- 구조체 또는 열거형에 대해 Togglable 프로토콜을 구현하면 해당 구조체 또는 열거형은 mutating 으로 표시된 toggle() 메서드의 구현을 제공하는 프로토콜을 준수
- OnOffSwitch 라는 열거형은 열거형 케이스 인 on 과 off 를 나타내기 위해 2개의 상태를 변경
- 이 열거형의 toggle 구현은 Togglable 프로토콜의 요구사항을 일치시키기 위해 mutating 으로 표시
초기화 구문 요구사항
- 프로토콜은 준수하는 타입에 의해 지정된 구현된 초기화 구문을 요구할 수 있음
- 일반적인 초기화 구문과 동일한 방식으로 명시적으로 프로토콜의 정의의 부분으로 초기화 구문을 작성하지만 중괄호 또는 초기화 구문 바디는 없이 작성
protocol SomeProtocol {
init(someParameter: Int)
}
프로토콜 초기화 구문 요구사항의 구현
- 지정된 초기화 구문 또는 편의 초기화 구문으로 준수하는 클래스에 프로토콜 초기화 구문 요구사항을 구현할 수 있음
- 이 모든 케이스에 대해 required 수식어와 함께 초기화 구문 구현에 표시해야 함
class SomeClass: SomeProtocol {
required init(someParameter: Int) {
// initializer implementation goes here
}
}
- required 수식어를 사용하면 준수하는 클래스의 모든 하위 클래스에 초기화 구문 요구사항의 명시적 또는 상속된 구현을 제공하여 프로토콜을 준수
- final 클래스는 하위 클래스를 생성할 수 없으므로, final 클래스에 required 수식어를 프로토콜 초기화 구문 구현에 표시할 필요 없음
- 하위 클래스가 상위 클래스의 지정된 초기화 구문을 재정의 하고 프로토콜로 부터 일치하는 초기화 구문 요구사항이 구현되면 required 와 override 수식어 둘 다 초기화 구문 구현에 표시
protocol SomeProtocol {
init()
}
class SomeSuperClass {
init() {
// initializer implementation goes here
}
}
class SomeSubClass: SomeSuperClass, SomeProtocol {
// "required" from SomeProtocol conformance; "override" from SomeSuperClass
required override init() {
// initializer implementation goes here
}
}
실패 가능한 초기화 구문 요구사항
- 프로토콜은 실패 가능한 초기화 구문에 정의 된대로 준수하는 타입에 대해 실패 가능한 초기화 구문 요구사항을 정의할 수 있음
- 실패 가능한 초기화 구문 요구사항은 준수하는 타입에 실패 가능하거나 실패 불가능한 초기화 구문에 의해 충족될 수 있음
- 실패 불가능한 초기화 구문 요구사항은 실패 불가능한 초기화 구문 또는 암시적 언래핑 된 실패 가능한 초기화 구문에 의해 충족될 수 있음
자료 출처
https://docs.swift.org/swift-book/LanguageGuide/Protocols.html
'iOS' 카테고리의 다른 글
Swift - Extensions (0) | 2023.03.05 |
---|---|
Swift - Concurrency (동시성) (0) | 2023.02.26 |
Swift - Protocol(준수에 대한 검사, 상속, 옵셔널 프로토콜, 확장) (4/4) (0) | 2023.02.19 |
Swift - Protocol(정의, 프로퍼티) (1/4) (0) | 2023.02.03 |
Table View의 Self-Sizing Cell (0) | 2022.08.10 |
Comments