프로토콜의 기본 문법
프로토콜 정의와 채택
protocol MyProtocol {
}
MyProtocol은 요구 사항을 선언하는 역할을 한다
- 실제로는 아무것도 구현하지 않지만, 채택하는 타입에서 요구사항을 반드시 구현해야 한다
class FamilyClass { }
class MyClass: FamilyClass, MyProtocol {
}
MyClass는 FamilyClass를 상속하면서 MyProtocol을 채택한다
- 클래스 상속은 먼저 선언하고, 그 후에 프로토콜을 선언해야 한다
struct MyStruct: MyProtocol {
}
- 구조체도 동일하게 프로토콜을 채택할 수 있다
- 구조체는 클래스와 다르게 상속이 없기 때문에, 바로 프로토콜을 선언하면 된다
enum MyEnum: MyProtocol {
}
- 열거형도 프로토콜을 채택하여 요구사항을 구현할 수 있다
프로토콜에서의 속성 요구사항 정의 - 속성 요구 사항 정의하기
프로토콜 속성의 요구사항
- 프로토콜에서 속성을 정의할 때는
var 키워드를 사용해야 함 (프로토콜은 상수 속성으로 선언할 수 없음)
get, set 키워드로 읽기/쓰기 여부를 설정 (최소한의 요구사항을 나타냄)
- 실제 구현은 저장 속성 또는 계산 속성으로 구현 가능
속성 요구사항의 의미
| 요구사항 | 저장 속성(Stored Property) | 계산 속성(Computed Property) |
|---|
{ get } | let, var | 읽기(get) 또는 읽기 / 쓰기(get / set) |
{ set } | var | 읽기 / 쓰기(get / set) |
프로토콜 정의 예시
protocol RemoteMouse {
var id: String { get }
var name: String { get set }
static var type: String { get set }
}
RemoteMouse 프로토콜은 3개의 요구 사항을 정의한다
• id: 읽기 전용 속성 (let, var, 계산 속성 모두 가능)
• name: 읽기/쓰기 가능한 속성 (var, 계산 속성)
• type: 타입 저장 속성 또는 타입 계산 속성 (static, class)
저장 속성으로 구현하기 (구조체)
struct TV: RemoteMouse {
var id: String = "456"
var name: String = "삼성티비"
static var type: String = "리모콘"
}
let myTV = TV()
print(myTV.id)
print(myTV.name)
print(TV.type)
TV 구조체는 RemoteMouse 프로토콜의 요구사항을 전부 구현한다
id, name 은 인스턴스 저장 속성으로 구현되었고, type 은 static 키워드를 사용하여 타입 저장 속성으로 구현되었다
타입(static) 속성 요구사항 - 최소한의 요구사항 지정
타입 속성 요구사항의 구현 방법
- 저장 타입 속성과 계산 타입 속성으로 모두 구현 가능
- 프로토콜 요구사항은 저장 속성인지 계산 속성인지 구별하지 않음
- 타입 속성의 구현은
static 또는 class 키워드를 사용하여 선언할 수 있음
저장 타입 속성으로 구현하기 (static)
class SmartPhone: RemoteMouse {
var id: String { "777" }
var name: String {
get { "아이폰" }
set { }
}
static var type: String = "리모콘"
}
print(SmartPhone.type)
SmartPhone 클래스는 RemoteMouse 프로토콜을 채택하여 모든 요구사항을 구현한다
type 속성은 static으로 선언되었으므로 저장 타입 속성으로 구현되었고, 재정의가 불가능하다
계산 타입 속성으로 구현하기 (class)
class Ipad: RemoteMouse {
var id: String = "777"
var name: String = "아이패드"
class var type: String {
get { "리모콘" }
set { }
}
}
print(Ipad.type)
Ipad 클래스는 RemoteMouse 프로토콜을 채택하여 모든 요구사항을 구현한다
type 속성은 class로 선언되었기 때문에 계산 타입 속성으로 구현되었고, 재정의가 가능하다
요약
- 프로토콜에서 속성을 정의할 때는
var 키워드를 사용하고, get, set 으로 읽기/쓰기 여부를 지정한다
- 저장 속성, 계산 속성 모두 구현할 수 있지만 요구사항만으로는 구별되지 않는다
- 타입 속성의 경우,
static 또는 class 키워드로 구현할 수 있다
• static: 저장 속성, 계산 속성 모두 가능하지만, 저장 속성은 재정의 불가
• class: 계산 속성으로만 구현 가능하며, 재정의가 가능하다