확장(Extension)이란 클래스, 구조체, 열거형 또는 프로토콜로 정의된 타입에 새로운 기능의 메서드를 추가하여 타입의 기능을 확장하는 문법입니다.
Swift에서 확장은 메서드(함수)형태만 가능합니다. (저장 속성 X)
확장으로 추가된 메서드는 상속이 가능하지만, 재정의는 불가능합니다. (func 앞에 "@objc" 키워드를 작성하면, 재정의가 가능)
✅ 확장으로 정의된 메서드 상속 (재정의는 불가)
🚨특별한 키워드 작성 없이 재정의할 경우 Non-@objc instance method 'add()' is declared in extension of 'A' and cannot be overridden 라는 문구의 에러가 발생합니다.
class A{ func a(){ print("저는 A입니다.") } } extension A{ // A클래스 기능 확장 func add(){ print("추가 메서드 입니다.") } } class B: A{ func b(){ print("저는 B입니다.") } } var kim = B() kim.add() // 상속 받아 사용
✅ 소급 모델링(retroactive modeling) + 계산 속성(프로퍼티) 추가
- 계산 속성은 함수처럼 연산이 가능한 특징을 가지고 있는 프로퍼티(함수 형태를 하고 있는 프로퍼티)이기 때문에 확장이 가능합니다.
extension String{ var selfIntroduce: String{ //계산 속성 get( ) return "저는 \(self) 입니다." } } print("김철수".selfIntroduce) // 저는 김철수 입니다.
✅ 인스턴스 메서드, 타입 메서드 정의
⚙️인스턴스 메서드 정의
extension Int{ func minusOne() -> Int{ return self - 1 } } print(10.minusOne()) // 9
⚙️타입 메서드 정의
타입 메서드는 class, static 키워드를 사용하여 정의합니다.extension Int{ static func typeIntroduce(){ print("저는 \(self) 타입 입니다.") } } Int.typeIntroduce() // Int형은 구조체로 이루어져있다.
✅ 클래스는 편의 생성자만 구현이 가능합니다.
- 클래스는 생성자 중에서 편의 생성자(Convenience Initializer)만 추가 가능합니다.
class ABC{ var a: Int var b: Int var c: Int init(a: Int, b: Int, c: Int){ self.a = a self.b = b self.c = c } func sum(){ print(a+b+c) } } extension ABC{ convenience init(n: Int){ //클래스는 편의 생성자만 추가 가능하다! self.init(a: n, b: n, c: n) } } var kim = ABC(n: 10) kim.sum() //var kim = ABC(a: 10, b: 10, c: 10) //kim.sum()
✅ 구조체는 다양한 형태의 생성자를 구현할 수 있습니다.
- 구조체는 클래스와 다르게 다양한 형태의 생성자를 추가하여 확장할 수 있습니다.
⚙️case1
struct ABC{ var a: Int var b: Int var c: Int // init(a: Int, b: Int, c: Int){ } 멤버와이즈 생성자(Memberwise Initializer) } extension ABC{ init(n: Int){ self.a = n self.b = n self.c = n } } var kim = ABC(n: 10) kim.a // 10
⚙️case2
struct ABC{ var a: Int = 1 var b: Int = 2 var c: Int = 3 } extension ABC{ init(a: Int){ self.a = a } } var kim = ABC(a: 10) kim.a // 10
✅ 클래스에 서브스크립트 추가
- 서브스크립트는 함수의 형태를 가지고 있으므로 추가 확장이 가능합니다.
class ABC{ var classFriend = ["짱구", "철수", "훈이", "유리", "맹구"] } extension ABC{ subscript(index: Int) -> String{ return classFriend[index] } } var man = ABC() man[2] // 훈이
✅ 새로운 커스텀 타입을 추가하여 확장
extension String{ enum Week{ case mon, tue, wed, thu, fri, sat, sun } var Day: Week{ switch self{ case "월": return Week.mon case "화": return Week.tue case "수": return Week.wed case "목": return Week.thu case "금": return Week.fri case "토": return Week.sat default: return Week.sun } } } var kim = "금" kim.Day // fri
참고자료: 앨런 Swift문법 마스터 스쿨