[Swift] Initializers (초기화) 사용법 & 예제 [1/2]

728x90

Initializers (생성자) 를 사용하는 이유


구조체 / 열거형 / 클래스와 같은 설계도를 기반으로 생성한 것을 ‘ 인스턴스’ 라고 합니다.

이 때 인스턴스의 초기화를 담당하는 것이 ‘생성자’ 입니다.
초기화를 사용하는 이유는 모든 속성을 기본값으로 초기화 해서 인스턴스를 기본값 상태를 만들기 위해서입니다.
확인은 생성자 실행 되었을때 모든 속성이 기본값을 가지고 있다는 뜻 입니다. (기본 값 없으면 초기화 실패)

  • Default Initializer
    아래와 같이 모든 속성이 초기화 되어 있을 경우 컴파일러가 기본 생성자를 생성해 주기 때문에 따로 작성 할 필요 가 없다.
class Position {
    var x = 0.0 // 속성이 항상 동일한 값으로 초기화 될때 사용 하는 방법
    var y = 0.0
    var z: Double? = nil// 기본값 저장 X -> 자동 nil초기화

    //    init() { // 파라미터 활용, 속성 초기화 할때 사용 하는 방법
    //        y = 0.0
    //}

}
let p = Position()

Initializers (초기화) 사용법 & 예제


Initializers

  • initializer Syntax
init(parameters) {
    initialization
}

Typename(parameters)

 

  • Default Initializer
class SizeObj {
    var width = 0.0
    var height = 0.0

    init(width: Double, height: Double) {
        self.width = width // 파라미터 이름과 속성 이름이 동일할 때 self 사용
        self.height = height
    }

    convenience init(value: Double) { //다른 생성자 호출 convenience , initialize delegate, 중복 피하기 위해(오버로딩 지원 -> 파라미터의 수, 자료형, argument lable로 구분)
        //width = value
        //height = value
        self.init(width: value, height: value) // 다른 생성자 호출할때 self
    }
}

 

  • Memberwise Initializer
struct SizeValue {
    var width = 0.0
    var height = 0.0
}

let s = SizeValue()
SizeValue(width: 1.2, height: 3.4) //init 구현 하지 않았을때 자동으로 제공됨 , 생성자 구현하면 더이상 사용할 수 없다.

Class Initializers

  • Designated Initializer
//init(parameters) {
//
//}
class Position {
    var x: Double
    var y: Double

    init(x: Double, y: Double) { //모든 속성을 초기화 해야 된다.
        self.x = x
        self.y = y
    }
}

 

  • Convenience Initializer
//convenience init(parameters) {
//    initialization
//}
class Position1 {
    var x: Double
    var y: Double

    init(x: Double, y: Double) { //모든 속성을 초기화 하지 않아도 된다. -> 나머지는 다른 생성자 호출(super class X)
        self.x = x
        self.y = y
    }

    //x만 초기화하는 convenience init
    convenience init(x: Double) {
        self.init(x: x, y: 0.0)
    }
}

 

  • Automatic Initializer Inheritance
class Figure {
    var name: String

    init(name: String) {
        self.name = name
    }

    func draw() {
        print("draw \(name)")
    }

    convenience init() {
        self.init(name: "unkown")
    }
}

class Rectangle: Figure { //상속의 생성자
    var width: Double = 0.0
    var height: Double = 0.0

    init(name: String, width: Double, height: Double) {
        self.width = width
        self.height = height
        super.init(name: name) //상위 구현 호출
    }

    override init(name: String) {
        width = 0
        height = 0
        super.init(name: name)
    }

    convenience init() { //동일한 클래스의 다른 생성자 호출 , 슈퍼클래스 직접 호출 X / overriding X
        self.init(name: "unkown")
    }
}

Required Initializer

//required init(parameters) {
//    initialization
//}
class Figure {
    var name: String

    required init(name: String) { //서브 클래스에서 반드시 동일한 생성자 구현해야 함
        self.name = name
    }

    func draw() {
        print("draw \(name)")
    }
}

class Rectangle: Figure {
    var width = 0.0
    var height = 0.0

    init() { // 상속 받지 않기 때문에 직접 구현해줘야함 requrired
        width = 0.0
        height = 0.0
        super.init(name: "unknown")
    }

    required init(name: String) { //super와 동일한 생성자 구현, overiding X , 완전히 동일한 형태 구현 강제
        width = 0.0
        height = 0.0
        super.init(name: name)
    }
}

Initializer Delegation

생성자 델리게이션을 통해 인스턴스가 초기화 되는 과정
초기화 코드에서 중복 최대한 제거,
모든 속성을 효율적으로 초기화 하기 위해 사용

 

생성자 델리게이션 규칙

 

  • rule1(delegate Up) : designated 생성자는 반드시 슈퍼 클래스의 designated 생성자를 호출해야 한다.

 

  • rule2(delegate Across) : convenience 생성자는 반드시 같은 클래스의 다른 생성자를 호출 해야한다.

  • rule3 : Convenience 생성자를 호출 했을 때 최종적으로는 반드시 designated 생성자가 호출 되어야 한다.

struct Size {
    var width: Double
    var height: Double

    init(w: Double, h: Double) {
        width = w
        height = h
    }

    init(value: Double) { // initializer delegation 생성자 위임 //모든 생성자 실행후 초기화 되어야 됨
        // 코드 단순, 유지보수 수월해짐
        self.init(w: value, h: value)
    }
}

예시

class Figure {
    let name: String

    init(name: String) {
        self.name = name //designated init
    }

    convenience init() {
        self.init(name: "unknown")
    }
}

class Rectangle: Figure {
    var width = 0.0
    var height = 0.0

    //Rule1(Delegate Up)
    init(n: String, w: Double, h: Double) {
        width = w
        height = h
        super.init(name: n)
    }

    convenience init(value: Double) {
        self.init(n: "rect", w: value, h: value)
    }
}

class Squre: Rectangle { //delegated up 불가 , self , super 실수 많다 , self임
    convenience init(value: Double) {
        self.init(n: "squre", w: value, h: value)
    }

    convenience init() {
        self.init(value: 0.0)
    }
}

위 코드 생성자 실행 순서


출처 : 어서와! Swift는 처음이지?(Programmers)
728x90

댓글

Designed by JB FACTORY