[Swift] 초기화 구문

민니·2022년 7월 11일
0

Swift 문법

목록 보기
12/17

초기화 ❓

  • 구조체나 클래스를 사용하기 위해 인스턴스를 생성해서 메모리 공간을 할당받는 과정
  • 기본 구문 이외의 형식으로 원하는 인자값을 전달하여 저장 프로퍼티를 초기화하려면 구조체나 클래스 내부에 초기화 메서드를 정의해야 함
  • 생성자라고 부르기도 함


init 초기화 메서드

초기화 메서드 형식

init(<매개변수> : <타입>, <매개변수> : <타입>, ...) {
	1. 매개변수의 초기화
    2. 인스턴스 생성 시 기타 처리할 내용
}

초기화 메서드 특성

  • 초기화 메서드의 이름은 init으로 통일
  • 매개변수의 개수, 이름, 타입은 임의로 정의
  • 매개변수의 이름, 개수, 타입이 서로 다른 여러 개의 초기화 메서드를 정의
  • 초기화 메서드는 대부분 인스턴스 생성 시 간접적으로 호출됨
    ✏️ 인스턴스 생성 구문과 매개변수 형식이 일치하는 초기화 메서드가 호출
    ✏️ 직접 호출하기도 가능
  • init 메서드가 작성되고 나면, 작성된 init 메서드의 인자값 형식과 관계 없이, 그 객체의 기본 초기화 구문은 더이상 사용 불가
  • 기본 초기화 구문을 사용하려면, 직접 init() 메서드 정의 필요
  • init 역시 메서드이므로, 기본값 지정 가능 ➡️ 인자값이 생략 가능하며, 생략된 인자값 대신 기본값이 인자값으로 사용

📚 Example - 하나의 초기화 메서드만 사용

struct Resolution {
    var width = 0
    var height = 0
    
    //초기화 메서드
    init(width: Int) {
        self.width = width
    }
}

class VideoMode {
    var resolution = Resolution(width: 2048)
    var interlaced = false
    var frameRate = 0.0
    var name: String?
    
    //초기화 메서드
    init(interlaced: Bool, frameRate: Double) {
        self.interlaced = interlaced
        self.frameRate = frameRate
    }
}

//let resolution = Resolution.init(width: 4096)
let resolution = Resolution(width: 4096)
//let videoMode = VideoMode.init(interlaced: true, frameRate: 40.0)
let videoMode = VideoMode(interlaced: true, frameRate: 40.0)
let defaultVideoMode = VideoMode() //error

✏️ defaultVideoMode: init 메서드가 작성된 후 기본 초기화 구문 사용 불가


📚 Example - 다양한 초기화 메서드

class VideoMode {
    var resolution = Resolution(width: 2048)
    var interlaced = false
    var frameRate = 0.0
    var name: String?
    
    init(name: String) {
        self.name = name
    }
    
    init(interlaced: Bool) {
        self.interlaced = interlaced
    }
    
    init(interlaced: Bool, frameRate: Double) {
        self.interlaced = interlaced
        self.frameRate = frameRate
    }
    
    init(interlaced: Bool, frameRate: Double, name: String) {
        self.interlaced = interlaced
        self.frameRate = frameRate
        self.name = name
    }
}

let nameVideoMode = VideoMode(name: "홍길동")
let simpleVideoMode = VideoMode(interlaced: true)
let doubleVideoMode = VideoMode(interlaced: true, frameRate: 40.0)
let tripleVideoMode = VideoMode(interlaced: true, frameRate: 40.0, name: "홍길동")


초기화 구문의 오버라이딩

  • 초기화 구문도 메서드이므로, 자식 클래스에서 오버라이딩 가능
  • override 키워드
  • 부모 클래스에서 기본 초기화 구문을 명시적으로 작성하지 않아도 기본 초기화 구문이 내장되어 있으므로, 자식 클래스에서는 오버라이딩해야 함

super.init

자식 클래스에서 초기화 구문을 오버라이딩하면 부모 클래스에서 정의한 초기화 구문이 실행되지 않음
if 부모 클래스의 기본 초기화 구문에서 프로퍼티를 초기화했다면, 자식 클래스에서 기본 초기화 구문을 오버라이딩함으로써 부코 클래스 프로퍼티의 초기화가 누락
-> 이를 방지하기 위해 오버라이딩된 초기화 구문 내부에 super.init 구문 작성

📚 Example

class Base {
    var baseBalue: Double
    
    init(inputValue: Double) {
        self.baseBalue = inputValue
    }
}

class ExBase: Base {
    override init(inputValue: Double) {
        super.init(inputValue: 10.5)
    }
}

✏️ Base 클래스에 작성된 init 구문은 baseValue 프로퍼티에 입력받은 인자값을 할당
✏️ ExBase에서 초기화 구문을 오버라이딩하면 ExBase에서 초기화할 때 baseValue에 대한 값 할당이 누락됨
✏️ 이러한 오류 를 방지하기 위해 오버라이딩된 초기화 구문에서 부모 클래스의 초기화 구문을 직접 호출 필요



초기화 구문 델리게이션

연쇄적으로 오버라이딩된 자식 클래스의 초기화 구문에서, 부모 클래스의 초기화 구문에 대한 호출이 발생하는 것

📚 부모 클래스에 기본 초기화 구분만 정의/명시적으로 정의되어 있지 않은 경우

  • super.init() 구문을 호출해 주지 않아도 자동으로 부모 클래스의 초기화 구문 호출
  • 초기화 구문의 호출은 자식 클래스부터 역순으로 이루어짐
class Base {
    var baseValue: Double
    
    init() {
        self.baseValue = 0.0
        print("Base Init")
    }
}

class ExBase: Base {
    override init() {
        print("ExBase Init")
    }
}

let ex = ExBase()

//결과
//ExBase Init
//Base Init

✏️ 기본 초기화 구문만 존재 -> 자동으로 부모 클래스의 초기화 구문을 호출해 준다
✏️ 실행 결과를 보면 호출이 자식 클래스부터 역순으로 이루어짐을 알 수 있음

📚 다른 형식의 초기화 구문이 있는 경우

  • 기본 초기화 구문을 오버라이딩할 때, 부모 클래스의 기본 초기화 구문을 호출해야 함
class Base {
    var baseValue: Double
    
    init() {
        self.baseValue = 0.0
        print("Base Init")
    }
    
    init(baseValue: Double) {
        self.baseValue = baseValue
    }
}

class ExBase: Base {
    override init() {
        super.init()
        print("ExBase Init")
    }
}

let ex = ExBase()

✏️ 기본 초기화 구문 이외에 다른 형식의 초기화 구문도 추가되어 있음
✏️ 자식 클래스에서 기본 초기화 구문을 오버라이딩할 때, 부모 클래스의 기본 초기화 구문 호출 필요





출처)
꼼꼼한 재은씨의 스위프트: 문법편

0개의 댓글