Swift 에서 initializer 들의 종류를 알아보자!!

Designated init, Convenience init, Required init 이렇게 세가지에 대해 간단하게 알아보자.

Designated init은 객체 모든 프로퍼티의의 값을 함수 구문 안에서 정해주는 initializer 이다.

Convenience init은 함수 내부에서 객체의 모든 프로퍼티를 코드로 정해주기 귀찮아서 Designated init을 사용하고 싶을 때 쓰는 것이다!

Required init은 자신을 상속받을 클래스들에게 반드시 선언해줬으면 하는 initializer 가 있을 때 사용하는 것이다!

 

Designated init

객체 안의 모든 프로퍼티의 값들을 초기화해줘야 하는 initializer다!

옵셔널 타입을 제외한 모든 프로퍼티들을 선언해줘야 한다.

class A{
    var propertyA: String
    var propertyB: String
    
    init(propertyA: String){
        self.propertyA = propertyA    //error!
    }
}

위 코드는 클래스의 프로퍼티 propertyB 값을 선언해주지 않았기 때문에 error가 난다.

따라서 제대로 된 Designated init 을 만들어줘보자!

 

class A{
    var propertyA: String
    var propertyB: String
    
    init(propertyA: String, propertyB: String){
        self.propertyA = propertyA
        self.propertyB = propertyB
    }
}

 

이제 Designated init 에 대해 알게되었다

 

Convenience init

Convenience init 에 대해 알아보자!

말 그대로 편리한 initialize 이다!   왜 편리하다고 하는 것일까?    

위처럼 propertyA, propertyB 를 하나하나 다 넣어주지 않아도 되는 initialization 을 만들어주는 것이다!!

 

propertyA 만 받는 A의 initializer 를 만들고 싶다면?

Convenience init 이 없다고 가정해보자!

class A{
    var propertyA: String
    var propertyB: String
    
    init(propertyA: String, propertyB: String){
        self.propertyA = propertyA
        self.propertyB = propertyB
    }
    
    init(propertyA:String){
        self.propertyA = propertyA
        self.propertyB = "propertyB"
    }
}

이렇게 할 수도 있지만..

A 클래스의 프로퍼티가 엄청 많아진다면 코드가 매우 길어질 것이다.

 

그래서 나온 것이 Convenience init 이다!

initalizer안에서 사전에 정의된 Designated init 을 반드시 실행해주는 initializer 라고 생각하면 된다!

class A{
    var propertyA: String
    var propertyB: String
    
    init(propertyA: String, propertyB: String){
        self.propertyA = propertyA
        self.propertyB = propertyB
    }

    //그냥 init 으로 하게 되면 함수 안에서 self.init을 사용할 수 없기 때문에  convenience을 붙여주자!
    convenience init(propertyA:String){
        self.init(propertyA: propertyA, propertyB: "propertyB")
    }
}

위 처럼 initializer 안에서 다른 initializer 를 사용하기 위해서,  

즉 몇 줄짜리 코드를  한줄로(다른 initializer로) 줄이기 위해서 사용하는 것이 Convenience initializer 이다!!

 

 

 

Required init

Required init 에 대해 알아보자!!

Required init 은 상속받을 클래스에서 주로 사용한다!!

만약에 subclass 들이 꼭 override 해주고 싶은 initializer 가 있다면?  

required init 으로 해주자!!

 

class A{
        var propertyA: String
        var propertyB: String
        
        init(propertyA: String, propertyB: String){
            self.propertyA = propertyA
            self.propertyB = propertyB
        }
        
        required init(){
            self.propertyA = "propertyA"
            self.propertyB = "propertyB"
        }
    }

A 를 위처럼 만들었다고 가정하자

 

 

이제 A를 상속받는 B 클래스를 만들어보자

class B: A{     //Error!!!
        override init(propertyA: String, propertyB: String) {
            self.propertyA = propertyA
            self.propertyB = propertyB
        }
    }

헉! 에러가 날 것이다

왜냐하면 A에 있는 required init 을 만들어주지 않았기 때문에

 

그럼 오류가 나지 않게 하는 방법을 알아보자!

class B: A{
        override init(propertyA: String, propertyB: String) {
            super.init(propertyA: propertyA, propertyB: propertyB)
        }
        
        required init() {
            super.init(propertyA: "propertyA", propertyB: "propertyB")
        }
    }

반드시 required init 을 만들어주고 그 함수 안에서

super 클래스의 아무 initializer 를 사용하여 모든 프로퍼티의 값을 넣어준다면 해결이 될 것이다

 

 

 

 

복사했습니다!