프로토콜 protocols 정의 채택, 프로토콜 프로퍼티, 프로토컬 메서드, 프로토컬 이니셜라이저, 프로토컬 익스텐션 (extension)/ Xcode SwiftUI Playground 공부
프로토콜(protocol)
특정 작업이나 기능에 적합한 메소드, 프로퍼티 등 기타 요구사항의 '약속'
- 클래스, 구조체, 열거형에서는 어떠한 프로토콜을 채택하여 해당 프로토콜의 요구사항을 실제로 구현할 수 있다.
- 프로토콜의 요구사항을 충족시키는 모든 타입은 해당 프로토콜을 준수한다 혹은 따른다고 한다
프로토콜 정의하기
1. protocol 키워드를 앞에 붙이고, 프로토콜의 이름을 작성합니다.
2. 아래는 SomeProtocol을 정의한 코드입니다.
protocol 이름 {
}
protocol SomeProtocol {
}
protocol SomeProtoco2 {
}
프로토컬 채택하기
1. 클래스, 구조체, 열거형에서 정의한 프로토콜을 채택 위해 콜론(:) 사용
struct SomeStructrue : SomeProtocol {
}
2. 하나의 타입에서 다수의 프로토콜을 채택하기 위해서는 콤마(,)를 사용
// 여러개의 프로토콜 채택하기
struct SomeStructrue2 : SomeProtocol, SomeProtoco2 {
}
3. 클래스에서 상속과 프로토콜 채택을 동시에 하려면 상속받으려는 클래스를 먼저 명시하고, 그 뒤에 채택할 프로토콜 목록을 작성
// 클래스 프로토콜 채택하기
//클래스에서 상속과 프로토콜 채택을 동시에 하려면 상속받으려는 클래스를 먼저 명시하고, 그 뒤에 채택할 프로토콜 목록을 작성합니다.
// SomeClass: SomeSuperclass, -> 상속
// FirstProtocol, AnotherProtocol -> 2개의 프로토콜
class SomeClass: SomeSuperclass, FirstProtocol, AnotherProtocol {
}
프로토콜의 프로퍼티 요구사항
프로토콜은 자신을 채택한 타입이 어떤 프로퍼티를 구현해야 하는지 요구할 수 있다
1. 프로퍼티는 타입과 이름만작성 (프로토콜이 프로퍼티에 준수하도록 정의할때 저장 프로퍼티인지 계산 프로퍼티인지 지정하지 않고 프로퍼티 이름과 타입만 정의하면 된다.)
2. gettable/settable 여부를 작성 (읽기만 가능한지 읽기 쓰기가 모두 가능한지 지정 / 프로토컬에서 읽기만 가능한 프로퍼티를 요구하는 경우 모든 종류의 프로퍼티를 사용할 수 있다)
3. 프로퍼티는 var로 선언해야 한다
protocol FirstProtocol {
var name: Int { get set}
var age: Int { get } // 읽기 전용
}
// 프로토콜에서 타입 프로토콜을 요구 할 때는 static 키워드를 사용해야 한다
protocol AnotherProtocol {
static var someTypeProperty: Int { get set}
}
// 프로토콜에서 프로퍼티 요구사항을 정의하고 구조체에 정의한 프로토컬 채택하기
protocol FullyNames {
var fullName: String { get set}
}
// 이렇게만 쓰면 에러
/*
프로토컬이 요구하는 사항을 모두 준수하지 않았다
struct Person: FullyNames {
}
*/
// 정의해주면 오류가 나지 않는다.
struct Person: FullyNames {
var fullName: String
}
프로토콜 메서드 / 프로토콜 메소드
1. 메소드는 함수명과 반환값을 지정할 수 있고,메소드 내용을 작성하지 않아도 된다
protocol FullyNames2 {
var fullName2: String { get set}
func printFullName2()
}
struct Person2: FullyNames2 {
var fullName2: String
func printFullName2() {
print(fullName2)
}
}
protocol SomeProtocol3 {
func someTypeMethod( )
}
프로토콜 이니셜라이저
1. 프로토콜에서는 필수로 구현해야하는 이니셜라이저를 지정할 수 있다
2. 이니셜라이저가 있는 프로토콜을 채택한 타입에서는 해당 이니셜라이저에 required 키워드를 작성해야 한다
protocol SomeProtocol4 {
init(someParameter: Int)
}
protocol SomeProtocol5 {
init( )
}
/*
// 생성자 요구사하 준수하지 않은 에러
class SomeClass: SomeProtocol5 {
}
*/
class SomeClass: SomeProtocol5 {
required init() {
}
}
프로토컬 익스텐션
extension ?
기존의 클래스, 구조체, 열거형, 프로토콜에 새로운 기능을 추가하는 기능
1. 익스텐션이 타입에 추가할 수 있는 기능
1) 연산 타입 프로퍼티 / 연산 인스턴스 프로퍼티
2) 타입 메서드 / 인스턴스 메서드
3) 이니셜라이저
4) 서브스크립트
5) 중첩 타입
6) 특정 프로포콜을 준수할 수 있도록 기능 추가
2. 이미 존재한 기능을 오버라이드 못함
extension 연산 프로퍼티 메서드 기능 추가
extension SomeType {
// 추가 기능
}
extension을 사용해 타입에 연산 프로퍼티를 추가하기
- 연산 프로퍼티는 추가가 가능하지만 저장 프로퍼티는 추가하지 못한다
// 짝수 홀수 판단하는 extension 프로퍼티 추가
extension Int {
// 짝수 true 홀수 false
var isEven: Bool{
return self % 2 == 0
}
var isOdd: Bool {
return self % 2 == 1
}
}
var number = 3
number.isOdd
number.isEven
타입의 메서드를 추가해보기
// 타입의 메서드를 추가해보기
// String 타입을 Int 타입으로으로 바꿔주기 (형변환)
extension String {
func convertToInt() -> Int? {
return Int(self)
}
}
var string = "0"
string.convertToInt()