본문 바로가기
iOS_Swift/문법 정리

Swift - 초기화 designated Initializer, convenience Initializer

by chozjjae 2022. 5. 4.

Initializer : 인스턴스 초기화하기

  • 클래스, 구조체, 열거형등 인스턴스가 생성되는 시점에서 해야 할 초기화 작업입니다.
  • 인스턴스가 만들어지면서 자동 호출됩니다.
  • self. - 현재 클래스 내 메서드나 프로퍼티를 가리킬 때 메서드나 프로퍼티 앞에 self. 을 붙입니다.
  • super. - 부모 클래스의 프로퍼티를 불러올 때 프로퍼티나 메서드 앞에 super. 을 붙입니다.
  • *초기화가 끝나기 전에 다른 메서드 호출은 불가능 합니다.

소멸자 

  • 인스턴스가 사라질 때 자동호출됩니다.
  • deinit{ }

*requiredinitializer

  • 자식 클래스에서 반드시 required 키워드로 재 작성해야하는 initializer입니다.
  • required init( ) { } //작성 법

 

designated initializer : 지정 이니셜라이져

  • 모든 프로퍼티(age, weight)를 다 초기화 시키는 생성자 입니다.
  • 초기화되지 않은 프로퍼티가 있을 경우 클래스에 반드시 1개 이상 있어야합니다.
class Man{
    var age : Int
    var weight : Double
    
    func display(){
        print("나이=\(age), 몸무게=\(weight)")
    }
    init(age:Int,weight:Double){
        self.age = age
        self.weight = weight
    }// designated initializer
}

var kim : Man = Man(age:20,weight:80)
kim.display()

//나이=20, 몸무게=80.0

 잘못된 designated initializer

두개의 프로퍼티 age, weight중 하나라도 초기화가 되지 않는다면 오류가 발생합니다.

class Man{
    var age : Int
    var weight : Double
    
    func display(){
        print("나이=\(age), 몸무게=\(weight)")
    }
    init(age:Int,weight:Double){
        //self.age = age 
        self.weight = weight
    }// designated initializer
}

var kim : Man = Man(age:20,weight:80)
kim.display()

//나이=20, 몸무게=80.0

 


convenience initializer : 편의 이니셜라이져

  • 보조 이니셜라이져입니다.
  • 일부 프로퍼티만 초기화가 가능합니다. *하지만 단독으로 초기화는 불가능
  • 다른 이니셜라이져를 이용해서 초기화합니다.
    • (initializer delegation) -> self.init( )
  • 다양한 방법으로 객체를 만들 수 있도록 편의를 제공하려면 init를 오버로딩 해야하고 그때 발생하는 코드 중복을 줄이기 위해서 사용합니다.
    • 코드 중복 방지
class Man{
    var age : Int
    var weight : Double
    func display(){
        print(age, weight)
    }
    init(age:Int, weight:Double){
        self.age = age
        self.weight = weight
    }//designated initializer
    
    convenience init(age:Int){
        self.init(age:age, weight:100)
    }//convenience initializer
    
}

var cho : Man = Man(age:20, weight:80)
cho.display() //20, 80.0

var kim : Man = Man(age:50)
kim.display() //50, 100.0

초깃값을 다른 initializer에서 지정해준다면 아래와 같이 소스코드 작성이 가능합니다.

class Man{
    var age : Int
    var weight : Double
    func display(){
        print(age, weight)
    }
    init(){
        self.age = 10
        self.weight = 20
    }//초깃값을 지정하는 init()
    init(age:Int, weight:Double){
        self.age = age
        self.weight = weight
    }//designated initializer
    
    convenience init(age:Int){
        self.init() //초기화 위임
        self.age = age //자신의 초기화 코드
    }//convenience initializer
    
}

var cho : Man = Man(age:20, weight:80)
cho.display() //20, 80.0

var kim : Man = Man(age:50)
kim.display() //50, 20.0

initializer 상속

  • 방법1 , designated initializer와 convenience initializer 모두 상속하는 경우
    • 자식 클래스에 designated initializer가 없는경우
    • 자식 클래스에 초기화가 필요한 프로퍼티가 없을 경우 
  • 방법2 , convenience initializer만 상속하는 경우
    • 자식 클래스에서 부모 클래스의 designated initializer를 override하는 경우 

방법 1 소스코드

방법1 , designated initializer와 convenience initializer 모두 상속하는 경우
class Man{
    var age : Int
    var weight : Double
    func display(){
        print(age, weight)
    }
    init(age:Int, weight:Double){
        self.age = age
        self.weight = weight
    }//designated initializer
    
    convenience init(age:Int){
        self.init(age:age, weight:100)
    }//convenience initializer
    
}
class son : Man{ //son 클래스에서 Man클래스를 상속 받았다
    //아무것도 작성하지 않아도 모두 상속받아온다.
}

var cho : Man = Man(age:20, weight:80)
cho.display() //20, 80.0

var kim : Man = Man(age:50)
kim.display() //50, 100.0

var cho1 : son = son(age:1, weight:2)
cho1.display()

var kim1 : son = son(age:5)
kim1.display()
print(kim.weight)

방법 2 소스코드

// 방법2 , convenience initializer만 상속하는 경우
class Man{
    var age : Int
    var weight : Double
    func display(){
        print(age, weight)
    }
    init(age:Int, weight:Double){
        self.age = age
        self.weight = weight
    }//designated initializer
    
    convenience init(age:Int){
        self.init(age:age, weight:100)
    }//convenience initializer
    
}
class son : Man{
    var name : String
    func display1(){
        print(name, age, weight)
    }
    init(age:Int, weight:Double, name:String){
        self.name = name
        super.init(age:age, weight:weight)
    }
    override init(age:Int, weight:Double){
        self.name = "홍길동"
        super.init(age:age, weight:weight)
    } //override를 작성해야 convenience initializer를 상속 할 수 있다.
    
}
//Man 클래스 호출
var cho : Man = Man(age:20, weight:80)
cho.display() //20, 80.0

var kim : Man = Man(age:50)
kim.display() //50, 100.0
//----------------------------------------------------------
//son 클래스 호출
var cho1 : son = son(age:1, weight:2, name:"chozjjae")
cho1.display1()

var hong : son = son(age:50)
hong.display1()

인덕대학교 한성현 교수님의 iOS강의를 참고하여 작성하였습니다.