티스토리 뷰

Swift/야곰의 스위프트

21장 익스텐션

할루루 2018. 3. 7. 23:22

[시작]


- 구조체, 클래스, 열거형, 프로토콜 타입에 새로운 기능을 추가할 수 있음

- 타입만 안다면 해당 타입의 기능을 확장할 수 있음

- 익스텐션이 타입에 추가할 수 있는 기능들

 : 연산 타입 프로퍼티 / 연산 인스턴스 프로퍼티

 : 타입 메서드 / 인스턴스 메서드

 : 이니셜라이저

 : 서브스크립트

 : 중첩 타입

 : 특정 프로토콜을 준수할 수 있도록 기능 추가

- 기존에 존재하는 기능을 재정의할 수는 없음

- 외부에서 가져온 타입에 내가 원하는 기능을 추가하고자 할 때 사용



[상속과 익스텐션 비교]


 

 상속

익스텐션 

 확장

수직 확장 (특정 타입을 물려받아 하나의 새로운 타입을 정의하고 추가 기능을 구현) 

수평 확장 (기존의 타입에 기능을 추가) 

 사용

클래스 

모든 타입 

 재졍의

가능 

불가능 




[문법]


- 일반


1
2
3
4
extension 확장할 타입 이름 {
    타입에 추가될 새로운 기능 구현
}
 
cs


- 기존에 존재하는 타입이 추가로 다른 프로토콜을 채택할 수 있도록 확장할 수 있음

1
2
3
4
extension 확장할 타입 이름: 프로토콜... {
    타입에 추가될 새로운 기능 구현
}
 
cs




[익스텐션으로 추가할 수 있는 기능 - 연산 프로퍼티]



1
2
3
4
5
6
7
8
extension Double{
    var meterToKilometer: Double {
        return self / 1000
    }
}
 
let meter = 17592.182
print(meter.meterToKilometer)   //17.592182
cs


위의 코드는 Double 타입에 익스텐션으로 미터를 킬로미터로 환산해주는 연산 프로퍼티를 확장함.


- 저장 프로퍼티는 추가할 수 없음

- 타입에 정의되어 있는 기존의 프로퍼티에 프로퍼티 감시자를 추가할 수 없음



[익스텐션으로 추가할 수 있는 기능 - 메서드]



1
2
3
4
5
6
7
8
9
10
11
12
13
14
extension Int{
    func multiply(by n: Int-> Int{
        return self * n
    }
    mutating func multiplySelf(by n: Int) {
        self = self * n
    }
    static func isIntTypeInstance(_ instance: Any) -> Bool{
        return instance is Int
    }
}
let a = 4
a.multiply(by: 5)           //20
Int.isIntTypeInstance(a)    //true
cs


위의 코드는 Int 타입에 익스텐션으로 여러 메서드를 추가함.


- 여러 기능을 여러 익스텐션 블록으로 나누어서 구현하면 코드를 좀더 보기 좋게 짤 수 있겠다.



[익스텐션으로 추가할 수 있는 기능 - 이니셜라이저]


- 클래스 타입에는 익스텐션으로 지정 생성자는 추가할 수 없고, 편의 생성자만 추가할 수 있음

- 지정 생성자와 소멸자는 반드시 클래스 타입의 구현부에 위치해야 함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
extension String{
    init(intTypeNumber: Int) {
        self = "\(intTypeNumber)"
    }
    init(doubleTypeNumber: Double) {
        self = "\(doubleTypeNumber)"
    }
}
let number = 13
let string = String(intTypeNumber: number)  //13 (String 타입)
 
class Person{
    var name: String
    init(name: String) {
        self.name = name
    }
}
extension Person{
    convenience init() {
        self.init(name: "Unknown")
    }
}
 
let person = Person()
person.name     //Unknown
 
cs


- 값 타입에 익스텐션으로 생성자를 추가했을 때, 

 : 모든 저장 프로퍼티에 기본값이 있고,

 : 타입에 기본 생성자와 멤버와이즈 생성자 외에 추가 사용자정의 생성자가 없다면,

 : 익스텐션으로 사용자정의 생성자를 추가한 이후에도 해당 타입의 기본 생성자와 멤버와이즈 생성자를 호출할 수 있음

   (타입 구현 시 생성자를 사용자정의하면 기존에 자동으로 생성되었던 생성자들을 사용할 수 없게 됨)



[익스텐션으로 추가할 수 있는 기능 - 서브스크립트]



1
2
3
4
5
6
7
8
9
10
11
12
13
14
extension String{
    subscript(appedValue: String-> String{
        return self + appedValue
    }
    subscript(repeatCount: UInt) -> String{
        var str: String = ""
        for _ in 0..<repeatCount{
            str += self
        }
        return str
    }
}
print("abc"["def"])     //abcdef
print("abc"[10])        //abcabcabcabcabcabcabcabcabcabc
cs




[익스텐션으로 추가할 수 있는 기능 - 중첩 데이터 타입]



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
extension Int{
    enum Kind{
        case negative, zero, positive
    }
    var kind: Kind{
        switch(self){
        case 0:
            return .zero
        case let x where x > 0:
            return .positive
        default:
            return .negative
        }
    }
}
 
let number = 42
print(number.kind)  //positive
 
cs


위 코드는 Int 타입에 열거형 타입과 그것의 연산 프로퍼티를 익스텐션으로 추가함

'Swift > 야곰의 스위프트' 카테고리의 다른 글

23장 프로토콜 지향 프로그래밍  (0) 2018.04.28
22장 제네릭  (0) 2018.04.27
20장 프로토콜  (0) 2018.03.01
19장 타입캐스팅  (0) 2018.03.01
18장 상속  (0) 2018.02.28
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함