본문 바로가기
iOS

[복습] Part 14. 확장

by 23g 2024. 9. 14.

1) 확장의 개념과 메모리 구조

상속과 확장의 비교

: 상속 = 수직 확장

데이터(저장 속성)를 추가하거나 기능을 변형 시켜 사용하는 것 / 클래스만 가능

class A{ }

class B: A{ } //B는 A를 상속함

 

확장 = 수평 확장

현재 존재하는 타입에서 기능(메서드)를 추가하여 사용하는 것 / 클래스, 구조체, 열거형 가능

class A { }

extension A { } // A를 확장

 

- 스위프트에선 확장에서 구현한 메서드에 대한 재정의 불가함

- 확장의 장점 : 원래 존재하는 타입에 기능을 확장하여 (개발자가 정의한대로) 사용 가능

2) 확장 가능 멤버 (속성과 메서드)

확장 가능 멤버의 종류

: 메서드 형태만 가능

 

가능 목록

1. (타입) 계산 속성, (인스턴스) 계산 속성

// 타입 계산 속성
extension Double{
	static var zero: Double { return 0.0 }
}

Double.zero //0.0

//인스턴스 계산 속성
extension Double {
	var km: Double { return self * 1000 }
 	var m: Double { return self }
}

let marathon = 42195.km
print("마라톤은 \(marathon)km 이다") // 마라톤은 42.195km 이다

2. (타입) 메서드, (인스턴스) 메서드 (-> 재정의는 불가함!)

// 타입 메서드
extension Int{
    static func print1to5(){
        for i in 1...5{
            print(i)
        }
    }
}

Int.print1to5()

// 인스턴스 메서드
extension String{
    func nPrint(n times: Int){
        for _ in 0..<times{
            print("Print: \(self)")
        }
    }
}

"hi".nPrint(n: 4)

// 구조체 인스턴스 메서드 속성 변경
extension Int{
    mutating func square(){
        self = self * self
    }
}

var someInt = 5
someInt.square()

3. 새로운 생성자 (클래스의 경우 편의 생성자만 추가 가능, 구조체 등은 예외적으로 지정 생성자 형태로도 가능)

import UIKit
//클래스의 경우
var color = UIColor(red: 0.3, green: 0.5, blue: 0.4, alpha: 1)

extension UIColor {      // 익스텐션 + 편의생성자 조합
    convenience init(color: CGFloat) {
        self.init(red: color/255, green: color/255, blue: color/255, alpha: 1)
    }
}

UIColor(color: 198)

// 구조체의 경우

// 방법 1 : 새롭게 확장에서 지정 생성자 구현
struct Point {
    var x = 0.0, y = 0.0
}

extension Point {
    init(value: Double) {
        self.x = value
        self.y = value
    }
}

//방법 2 : 생성자 구현 후 본체의 지정 생성자 호출
struct Point {
    var x = 0.0, y = 0.0
    
    init(x: Double, y: Double) {
        self.x = x
        self.y = y
    }
}

extension Point{
    init(){
        self.init(x: 0.0, y: 0.0)
    }
}

 

헷갈리는 확장-생성자 조건 정리!

 

확장

- 클래스 : 편의 생성자만 구현 가능

- 이외 : 지정 생성자의 형태로도 구현 가능 (상속과 관련 없기 떄문)

솔직히 이해 잘 안됨..ㅎ

 

4. 서브 스크립트

// n의 자리 반환하도록 만들기

extension Int{
    subscript(num: Int) -> Int{
        var decimalBase = 1
        
        for _ in 0..<num{
            decimalBase *= 10
        }
        return (self / decimalBase) % 10
    }
}

5. 새로운 중첩 타입 정의 및 사용

extension Int{
    
    enum Kind{
        case negative, zero, positive
    }
    
    var kind: Kind{
        switch self{
        case 0:
            return Kind.zero
        case let x where x > 0:
            return Kind.positive
        default:
            return Kind.negative
        }
    }
}

6. 프로토콜 채택 및 관련 메서드

extension SomeType: SomeProtocol{
	//확장 구현
}

 

 

불가능 목록

1. 저장 속성

2. 클래스의 지정 생성자