본문 바로가기

Swift/Deep dive!!

[Swift] class 초기화. 왜 super.init()을 쓰는가? (오버로딩, 오버라이딩)

 

 

 

 


클래스와 초기화(Initialization)

 

Swift는 클래스에서 저장 프로퍼티를 자동적으로 초기화 해주지 않는다. 

멤버와이즈 초기화 메서드를 지원해주는 구조체와 달리 개발자가 직접 명시적인 초기화를 통해 클래스 내 존재하는 모든 저장 프로퍼티들의 값을 넣어주어야 한다.

/**
 * x = 변수 선언과 동시에 값 할당
 * y = init()을 통해 초기화
 */
class point
{
    var x : Int = 0
    var y : Int
    init()
    {
        y = 0
    }
}

이 외에는 옵셔널 타입으로 만들면 초기화를 하지 않아도 자동으로 nil타입으로 초기화를 해준다.


상속받는 클래스의 경우 

 

만약 클래스 초기화를 할 때 해당 클래스가 상속을 받는 자식 클래스에 해당 할 경우. 부모 클래스의 프로퍼티를 상속받는다.

이때 C++과는 달리 자식클래스에서 init()을 구현할 경우 부모 클래스의 초기화 메서드를 호출하지 않는 한 부모 프로퍼티는 초기화 되지 않는다. 따라서 자식 클래스에서 부모 프로퍼티까지 전부 초기화를 해야한다.

다시 말해, 자식 클래스에서 init() 메서드를 정의 할 경우 부모 클래스의 저장 프로퍼티를 초기화 하기 위한 초기화 메서드는 호출되지 않기에 자식 클래스의 초기화에서 전 부 초기화를 해주어야 한다는 말이다.

이 경우 개발자가 직접 초기화 하지 못할 프로퍼티가 생길 수 있다.

따라서 자식클래스에서는 이전 부모 클래스의 초기화 함수를 override 한 override init()를 통해 초기화를 함과 동시에

부모 클래스의 초기화 함수를 명시적으로 호출해서 부모 클래스의 저장 프로퍼티까지 전부 자식 클래스 초기화 메서드 내에서 값을 할당해주는 번거로움이 덜어지는 것이다.

 

이전에 부모 클래스에서 선언했던 init()을 호출하면된다.


오버라이딩(Override)과 오버로딩(Overloading)

 

위 사진에서 보았듯이 자식 클래스에서 초기화 함수를 선언하는데 왜 override 키워드를 써야 하는가?

그 이유를 모른다면

 

우선 오버라이딩과 오버로딩의 개념에 대해서 알아야 한다.

  • 오버라이딩(Override). 함수 재정의
자식 객체에서 메서드를 선언할 때 이미 부모 클래스에 있는 경우 중복해서 사용하게 된다면 컴파일러는 부모의 메서드를 호출하는 것인지 자식의 메서드를 호출하는 것인지 잘 몰라 에러를 발생시킨다 (에휴..)
이때 사용하는 것이 Override 키워드이다.

즉 부모클래스에 있던 메서드를 자식클래스에서 Override 키워드를 사용하여 새롭게 재정의 하는 것이다.

이제 컴파일러는 오버라이딩된 자식 메서드를 호출한다.

 

그렇다면 부모 메서드는? super키워드를 사용하면 부모 메서드에 접근 할 수 있다.

 

  • 오버로딩(Overloading). 

다형성이라고 말할 수 있다.

이름은 같으나 매개변수를 달리해서 특정한 목적에 따라 다른 값을 부여할 수 있도록 해주는 함수이다.

 

그렇다면 이제는 설명할 수 있다.

위 사진에서 부모 클래스인 Point는 init() 메서드를 갖고있다.

자식클래스에서 init()을 사용하기 위해선 override 키워드를 사용해야만 컴파일 에러 먹지 않고 구현할 수 있는 것이다.

그렇다면

이 매개변수 있는 init(ox : Int?, oy : Int?) {} 이 메서드는 override를 써주어야 하는가?

 

No! 이것은 부모 클래스에는 없고, 자식클래스에서 다형성을 추구하기 위해 새롭게 구현한 메서드이다.(오버로딩)