본문 바로가기

스위프트

스위프트 튜토리얼(12) - Initializer

스위프트 튜토리얼(12) - Initializer

youtu.be/Ulp1Kimblg0?t=7045

이 포스팅은 위 영상을 보고 작성하는 것이다. (01:57:2602:05:41)

 

이니셜라이저Initiallizer에 대해 알아보도록 하자. 우리 나라 말로는 생성자라고 불리기도 한다.

클래스를 통해 객체를 만들 때 이 이니셜라이저를 이용하면 객체를 커스터마이징 할 수 있다. 잘 모르겠으면 예시가 가장 이해하기 빠르다. 예문을 보도록 하자.

 

class Person {
  var name = ""
  var age = 0
}

여기 Person이라는 클래스가 있다. name과 age라는 프로퍼티를 가지고 있다. 이 클래스를 이용해 객체를 만들어 보자.

 

var a = Person()

a에 객체가 할당되었고 a의 name은 현재 빈 문자열이고 age는 0이라 할 수 있다.

 

Person 뒤에 있는 괄호는 사실 Person 클래스의 이니셜라이저를 호출하는 것이라 볼 수 있다. 그런데 처음 보는 사람은 궁금할 것이다.

"나는 이니셜라이저라는 것을 만들지도 않았고, 어디있는지도 모르는데 어떻게 쓰는 거야?"

 

사실 이니셜라이저는 기본적으로 다음과 같은 형태를 띠고 있다.

init(){
}

 

이니셜라이저가 포함된 클래스를 표현하자면 다음과 같다.

class Person {
  var name = ""
  var age = 0
  
  init(){
  }
}

 

이니셜라이저는 클래스를 만든다면 기본적으로 포함되어있는 함수라고 보면 된다. 즉, 우리가 작성하지 않아도 있다는 뜻이다. 이니셜라이저는 커스터마이징 할 수도 있는데 예시를 보도록 하자.

class Person {
  var name = ""
  var age = 0
  
  init(){
    name = "Chris"
    age = 33
  }
}

let a = Person()
print(a.name)
print(a.age)

 

이니셜라이저 함수를 커스터마이징했고 이 이니셜라이저를 커스터마이징한 클래스를 통해서 객체를 만들었다. 객체의 프로퍼티 값은 달라졌음을 확인할 수 있다.

 

이니셜라이저는 매개변수도 받을 수 있다. 다음 예시를 보도록 하자.

 

class Person {
  var name = ""
  var age = 0
  
  init(n:String, a:Int){
    name = n
    age = a
  }
}

let a = Person(n : "Chris", a : 33)
print(a.name)
print(a.age)

 

init함수가 n과 a의 값을 받도록 변경했다. 따라서 객체를 생성할 때 여기 필요로 하는 매개변수를 넘겨주면 된다.(let a = Person(n : "Chris", a : 33)

 

다음과 같이 매개변수 레이블을 정하지 않고 바로 받도록 만들 수도 있다.

class Person {
  var name = ""
  var age = 0
  
  init(_ n:String, _ a:Int){
    name = n
    age = a
  }
}

let a = Person("Chris", 33)
print(a.name)
print(a.age)

 

그런데 만약 init의 parameterName과 클래스의 프로퍼티의 이름이 같을 수 있다. 예시로 보는 게 역시 이해하는 게 빠르다.

class Person {
  var name = ""
  var age = 0
  
  init(_ name:String, _ age:Int){
    name = name // 오류 발생
    age = age // 오류 발생
  }
}

 

저렇게 작성하면 name과 age과 Person 클래스의 프로퍼티 이름인지 함수 파라미터의 이름인지 모른다. 이 같은 경우를 피하기 위해 다음과 같이 작성한다.

class Person {
  var name = ""
  var age = 0
  
  init(_ name:String, _ age:Int){
    self.name = name  // self 사용
    self.age = age  // self 사용
  }
}

self라고 앞에 적어줌으로써 클래스의 프로퍼티라는 것을 명시할 수 있다. 이 Person 클래스를 글로써 설명한다면 다음과 같다.

 

"클래스를 통해서 객체를 생성할 때 name과 age를 받도록 하고 같은 프로퍼티 이름의 값으로 들어간다."

 

이니셜라이저를 위와 같이 재정의 했다면 파라미터가 없는 Person()과 같은 형태로 객체를 생성할 수가 없어진다. 가능하게 만들 수 있는 방법은 이니셜라이저를 하나 더 만드는 것이다. 

 

그렇다. 이니셜라이저는 두 개 이상 만들 수 있다.

 

그럼 두 개의 이니셜라이저를 가진 클래스를 만들어 보겠다.

class Person {
  var name = ""
  var age = 0
  
  init(){
  }
  
  init(_ name:String, _ age:Int){
    self.name = name  // self 사용
    self.age = age  // self 사용
  }
}

 

그럼 각각 다른 이니셜라이저를 사용해서 객체를 생성해보자.

var a = Person("Chris", 33) // name이 "Chris"이고, age가 33인 객체 생성
var b = Person() // name이 ""이고, age가 0인 객체 생성

프로퍼티의 값이 다른 두 객체를 만들 수 있다.

 

다음 포스팅에 더 자세히 적겠지만 지금 작성한 Person클래스의 경우 프로퍼티를 사용하든 사용하지 않든 프로퍼티의 값을 할당하게 만들어 놓고 있다. 다음 포스팅에서는 값을 사용할 때만 이니셜라이저를 통해 선언하고 값을 할당할 수 있도록 해보자