[Swift 기초] 익스텐션

2022. 4. 5. 19:14Swift 기초 정리

728x90

//공부 기록용 포스팅입니다. 틀린 부분이 있을 경우 댓글로 알려주시면 감사합니다! 😎

 

 

 

익스텐션은 구조체, 클래스, 열거형, 프로토콜 타입에 새로운 기능을 추가할 수 있는 기능

1. 익스텐션의 특징

  • 익스텐션(extension): 기존의 코드 변경 없이 기능을 추가할 수 있다.
    • 익스텐션은 모든 타입에 적용할 수 있다: 구조체, 열거형, 클래스, 프로토콜, 제네릭 타입 등
  • 타입만 알고 있다면 그 타입의 기능을 확장할 수 있다.
    • 모든 타입에 연산 프로퍼티, 메서드, 이니셜라이저, 서브스크립트, 중첩 데이터 타입 등을 추가할 수 있다.
  • 기능을 추가할 수 있지만, 기존에 존재하는 기능을 재정의 할 수 없다.
  • 프로토콜과 함께 사용하면 더욱 강력

1-1. 클래스와 익스텐션 비교

  상속 익스텐션
확장 수직확장 수평확장
사용 클래스타입 클래스, 구조체, 프로토콜, 제네릭 등 모든 타입
재정의  가능 불가능
  • 클래스의 상속은 특정타입을 물려받아 하나의 새로운 타입을 정의하고 추가 기능을 구현하는 수직확장
  • 익스텐션은 기존의 타입에 기능을 추가하는 수평 확장
    • 스위프트 표준 라이브러리에 정의되어 있는 타입은 실제 구현 코드를 수정할 수 없다.
      → 익스텐션, 프로토콜, 프로토콜의 초기구현을 사용하면 가져온 타입에 내가 원하는 기능을 추가할 수 있다.
  • 상속을 받으면 기존 기능을 재정의할 수 있다.
  • 익스텐션은 재정의 할 수 없다.

 

2. extesion: 익스텐션

extension 확장할 타입 이름 {
	/* 타입에 추가될 새로운 기능 구현*/
}

//ex
extension Double {
	
}
  • extension 키워드를 사용해서 기존의 Double 클래스에 추가하려는 인스턴스화(instanced) 메서드를 생성할 수 있다.
    • 인스턴스화 메서드: 선언된 프로그램에만 존재하기 때문, 즉 영구적으로 Double 클래스 변경 X
  • 스위프트 표준 라이브러리 타입의 기능은 대부분 익스텐션으로 구현되어 있다.

2-1. 익스텐션 확장(+프로토콜)

  • 기존에 존재하는 타입이 추가적으로 다른 프로토콜을 채택할 수 있도록 확장할 수 있다.
extension 확장할 타입 이름: 프로토콜1, 프로토콜2, 프로토콜3... {
	/*프로토콜 요구사항 구현*/
}

//ex
extension String: protocol1, protocol2 {

}
  • 클래스를 이미 구현한 후에 수정할 필요가 생겼다
    • 클래스 코드를 수정할 수 있지만, extension을 통해서 클래스를 확장시킬 수도 있다.
    • 확장구문에서 프로토콜을 구현한 다면 이후로 해당 클래스는 프로토콜을 구현한 것으로 처리
    • 기존 클래스를 수정하지 않아도 된다.
class Guest{
    var name: String?
    init(name: String = "ㄱㅅㄱ"){
        self.name = name
    }
}

protocol Reservation {
    func printReservation()
}

//Guest 클래스의 기능을 extension을 통해서 확장
extension Guest: Reservation {
    func printReservation(){
        print("\\(self.name) 님이 예약하였습니다.")
    }
}

var guest = Guest(name: "ㄱㅅㄱ")
guest.printReservation() //Optional("ㄱㅅㄱ") 님이 예약하였습니다.
  • 프로토콜을 정의할 때는 그 프로토콜을 채택한 타입에서 구현해주어야 하는 프로토콜의 요구사항을 구현할 수 없다. 단지 요구사항을 정의만 할 수 있다.
  • 프로토콜의 익스텐션에는 프로토콜이 요구하는 기능을 실제로 구현해 줄 수 있다.
    • 다만 익스텐션에는 저장 프로퍼티를 구현할 수 없으므로 저장 프로퍼티는 각각의 타입에서 직접 구현
    • 프로토콜 초기 구현(protocol default implementations): 프로토콜의 요구사항을 익스텐션을 통해 구현하는 것 → 프로토콜 채택만으로 타입에 기능을 추가해 사용할 수 있다(프로토콜 지향 프로그래밍 Protocol Oriented Programming POP의 핵심 콘셉)
  • 프로토콜의 익스텐션에서 구현한 기능을 사용하지 않고 타입의 특성에 따라 조금 변경해서 구현하고 싶다면 재정의하면 된다.

 

3. 익스텐션 구현

3-1. 연산 프로퍼티 추가

  • 연산 프로퍼티(computed property): 값을 저장하지 않는 대신 연산 결과를 반환한다.
    • getter, setter 연산 속성의 값을 지정하거나 가져오는 코드
    • 읽기 전용 연산 속성: 값 지정은 안되고 가져오기만 가능, getter 코드 블록만 갖는다.
      extension Int {
          var isEven: Bool {
              //코드 블록의 표현식에서 반환된 값을 속성에 저장
              return self % 2 == 0
          }
          var isOdd: Bool {
              return self % 2 == 1
          }
      }
    • 코드 블록: 연산 속성의 값을 계산하는 getter 코드
    • self 속성을 호출했던 Int의 값을 참조하며, 계산하기 위한 표현식에서 사용
      //숫자를 쓰게 되면 정수타입: Int타입의 인스턴스를 나타내는 리터럴 문법
      print(1.isEven) // false
      print(2.isOdd)  // false
      
      var number: Int = 3
      print(number.isEven) // false
      print(number.isOdd) // true
      
      number = 2
      print(number.isEven) // true
      print(number.isOdd) // false
  • 익스텐션으로 Int타입에 추가해 준 연산 프로퍼티는 Int타입의 어떤 인스턴스에도 사용이 가능합니다

3-2. 메서드 추가

extension Int {
    func multiply(by n: Int) -> Int {
        return self * n
    }
}

//Int 타입의 리터럴문법 -> Int 타입의 인스턴스로 취급
print(3.multiply(by: 2))  // 6
print(4.multiply(by: 5))  // 20

number = 3
print(number.multiply(by: 2))   // 6
print(number.multiply(by: 3))   // 9
  • 여러 기능을 여러 익스텐션 블록으로 나눠서 구현해도 문제없다.
  • 관련된 기능별로 하나의 익스텐션 블록에 묶어주는 것도 좋다.

3-3. 이니셜라이저 추가

extension String {
	//String 타입의 이니셜라이저를 따로 만들어준 것과 같은 효과
    init(int: Int) {
        self = "\\(int)"
    }
    init(double: Double) {
        self = "\\(double)"
    }
}

let stringFromInt: String = String(int: 100)  // "100"
let stringFromDouble: String = String(double: 100.0)  // "100.0"

print(stringFromInt is Int)  //false
print(stringFromInt is String)  //true
  • 타입의 정의부에 이니셜라이저를 추가하지 않더라도 익스텐션을 통해 이니셜라이저를 추가할 수 있다.

 

 

 

참고하였습니다. 감사합니다.

https://yagom.net/courses/swift-basic/lessons/타입-확장/topic/익스텐션/

https://yagom.net/courses/swift-basic/lessons/프로토콜-지향-프로그래밍-p-o-p/

https://www.inflearn.com/course/창원대학교-박동규-교수의-swift-기초-강좌/lecture/1903?tab=note&mm=null 

23.07.10 수정) Swift 쉽게, 더 쉽게

https://www.yes24.com/Product/Goods/17652267

728x90