프로토콜
프로토콜 : 특정 역할을 하기 위한 메서드, 프로퍼티, 기타 요구사항등의 청사진
구조체, 클래스, 열거형은 프로토콜을 채택해서 특정기능을 실행하기 위한 프로토콜의 요구사항을 실제로 구현할 수 있다.
이때 프로토콜이 요구하는 사항을 모두 충족하면 해당 타입이 채택한 프로토콜을 준수한다고 한다.
프로퍼티 요구사항
프로토콜은 자신을 채택한 타입이 어떤 프로퍼티를 구현해야 하는지 요구할 수 있다. 프로토콜이 프로퍼티에 준수하도록 정의할 때 저장프로퍼티인지 계산프로퍼티인지 지정하지 않고 프로퍼티 이름과 타입만 지정하면 되며 이때 프로퍼티에 읽기만 가능한지 읽기 쓰기 둘다 가능한지 get과 set을 이용해 지정해야 한다. 프로토콜에서 읽기만 가능한 프로퍼티를 요구하는 경우에는 모든 종류의 프로퍼티를 설정 할 수 있다.
코드로 확인
프로토콜 정의
import Foundation
/* 복붙
protocol 이름 {
}
*/
protocol SomeProtocol {
}
protocol Someprotocol2 {
}
struct SomeStructure: SomeProtocol, Someprotocol2 {
}
/* 클래스 상속의 경우 슈퍼클래스 이름 먼저 작성
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
}
*/
프로퍼티요구사항
프로토콜은 프로퍼티를 요구할 때 항상 변수로 요구해야하며 타입선언후에 get, set 을 이용해 읽고 쓰기가 가능한지 읽기만 가능한지 정해줘야 한다.
protocol FirstProtocol {
var name: Int { get set } //읽고 쓸 수 있다
var age: Int { get } //읽기만 가능하다
}
프로토콜에서 타입프로퍼티를 요구하려면 항상 static 키워드를 사용해야한다.
protocol AnotherProtocol {
static var SomeTypreProperty: Int { get set }
}
프로토콜 준수
프로토콜을 준수하지 않았을 때
protocol FullyNames {
var fullname: String { get set }
}
struct Person: FullyNames {
}
//Type 'Person' does not conform to protocol 'FullyNames'
프로토콜을 준수했을 때
protocol FullyNames {
var fullname: String { get set }
}
struct Person: FullyNames {
var fullname: String
}
프로토콜에서 정의한 프로퍼티 요구사항을 구조체에 정의해주면 오류가 사라지고 구조체는 프로토콜을 준수한다고 할 수 있다.
메서드 요구사항
프로토콜은 자신을 채택한 타입에 인스턴스 메서드, 타입 메서드를 요구할 수 있다
프로토콜에서 메서드를 정의 할때 중괄호나 메서드의 본문은 필요가 없지만 메서드에 필요한 매개변수는 정의해 주어야 하는데 이때 매개변수의 디폴트값은 지정 할 수 없다.
protocol FullyNames {
var fullName: String { get set }
func printFullName()
}
struct Person: FullyNames {
var fullName: String
func printFullName(){
print(fullName)
}
}
생성자 요구사항
프로토콜은 자신을 채택한 타입의 생성자도 요구 할 수 있다.
클래스에서 프로토콜이 요구하는 생성자를 채택하려면 'required' 식별자를 사용해야 하지만 클래스가 상속받을수 없는 파이널클래스라면 required 클래스를 붙여줄 필요가 없다.
protocol Initializer {
init()
}
class InitClass: Initializer {
required init(){
}
}
End