스위프트 프로토콜 기본, extension과 프로토콜
25 Nov 2017 | protocol swift extension프로토콜
프로토콜은 타입이 만족시킬 인터페이스를 정의할 때 필요하다. 타입이 프로토콜을 만족시킬때 프로토콜을 준수한다고 말한다.
프로토콜은 타입 자체로 사용될 수 있어서 프로토콜 타입을 가지는 변수나 함수 인수 리턴값을 사용할 수 있다.
프로토콜이 필요할때
func printTable(_ data: [[String]], withColumnLabels columnLabels: String...) {
var firstRow = "|"
var columnWidths = [Int]()
...
- 이 함수는 행과 열이 몇 개인지 알아야 한다. 인수를 두 개 받아서 반복문으로 table을 출력하는 함수이다. 하지만 프로토콜을 이용해서 TableData를 정의한 프로토콜만 받아도 작동되게 설계할 수 있다.
프로토콜 정의
...
protocol TableDataSource {
var numberOfRows: Int {get}
var numberOfColumns: Int {get}
func label(forColumn column: Int) -> String
func itemFor(row: Int, column: Int) -> String
}
get
문법은 프로퍼티가 읽기용이라는뜻이다.- 프로토콜은 타입이 이런 프로퍼티와 메서드만큼은 가져야한다는 최소 요건을 정의한다. TableDataSource 를 준수하는 타입들은 numberOfRows, numberOfColumns프로퍼티, label(), itemFor()메서드를 반드시 구현해야한다.
프로토콜 사용
정의한 프로토콜 TableDataSourse를 준수하는 Department 구조체를 만든다. 위에서 언급했듯이 프로토콜을 추상클래스처럼 사용할 수 있어서, 이 구조체는 TableDataSource타입이 되고 TableDataSourse타입처럼 사용될 수 있다. (ex TableDataSource를 인자로 받는 함수에 Department가 들어갈 수 있음)
struct Person {
let name: String
let age: Int
let yearOfExperience: Int
}
struct Department: TableDataSource { //TableDataSource 프로토콜을 준수함
let name: String
var people = [Person]()
init (name: String) {
self.name = name
}
mutating func add (_ person: Person) {
people.append(person)
}
// 프로토콜에 정의된 numberOfRows와 numberOfColumns는 {get}방식 읽기용 프로퍼티
var numberOfRows: Int {
return people.count
} //var numberOfRows: Int = people.count같음 (이렇게는 사용못함!)
var numberOfColumns: Int {
return 3
}
// 사용할때 column순서만 정해주면 매칭되는 케이스에서의 문자열을 리턴
func label(forColumn column: Int) -> String {
switch column {
case 0: return "Employee Name"
case 1: return "Age"
case 2: return "Years of Experience"
default: fatalError("Invalid column")
}
}
// Department의 프로퍼티인 Person리스트에서의 person정보를 조회. 행/열 번호만 정해주면 해당 person객체의 속성을 반환
func itemFor(row: Int, column: Int) -> String {
let person = people[row]
switch column {
case 0: return person.name
case 1: return String(person.age)
case 2: return String(person.yearOfExperience)
default: fatalError("Invalid column!")
}
}
}
extension에 프로토콜적용
extension
은 이미 존재하는 클래스나 구조체, 열거형 등의 객체에 새로운 기능을 추가하여 확장할 수 있는 키워드이다.
extension
은 라이브러리나 프레임워크에 포함되어 직접 접근할 수 없는 객체라도 확장 구문을 이용하면 제약 없이 새로운 기능을 추가할 수 있다.
또한 extension
에 프로토콜을 적용할 수 있다.
프로토콜과 관련된 확장의 특징 중 하나는 기존 객체를 수정하지 않고도 프로토콜을 구현할 수 있다는 것이다.
<String
과 Dictionary
의 확장 구문에 프로토콜 구현>
protocol ConvertTarget{
}
extension String: ConvertTarget {
}
extension Dictionary: ConvertTarget {
}
// String과 Dictionary는 프로토콜로 인해 ConvertTarget타입으로 한꺼번에 사용 할 수 있게 되었다.
Comments