🔥 오버라이딩

674자
10분

서브클래스에서는 수퍼클래스로부터 상속받은 인스턴스 메서드, 타입 메서드, 인스턴스 속성, 타입 속성, 서브스크립트를 자신만의 구현으로 재정의할 수 있습니다. 이를 오버라이딩(Overriding)이라고 합니다.

오버라이딩을 하려면 재정의하려는 특성 앞에 override 키워드를 붙여주면 됩니다. 이는 의도적으로 오버라이딩을 하는 것임을 명확히 하고, 실수로 매칭되는 정의를 제공하지 않았음을 나타냅니다. 실수로 오버라이딩을 하면 예상치 못한 동작이 발생할 수 있고, override 키워드 없이 오버라이딩하면 컴파일 시 오류로 진단됩니다.

override 키워드는 또한 Swift 컴파일러가 오버라이딩하는 클래스의 수퍼클래스(또는 그 상위 클래스 중 하나)에 오버라이딩에 제공한 선언과 일치하는 선언이 있는지 확인하도록 합니다. 이 검사는 오버라이딩 정의가 올바른지 확인해줍니다.

수퍼클래스의 메서드, 속성, 서브스크립트 접근하기

서브클래스에서 메서드, 속성, 서브스크립트를 오버라이딩할 때, 때로는 오버라이딩의 일부로 기존 수퍼클래스 구현을 사용하는 것이 유용할 수 있습니다. 예를 들어, 기존 구현의 동작을 개선하거나, 상속된 변수에 수정된 값을 저장할 수 있죠.

이런 경우 super 접두사를 사용하여 수퍼클래스 버전의 메서드, 속성, 서브스크립트에 접근할 수 있습니다:

  • 오버라이딩된 메서드 someMethod()는 오버라이딩 메서드 구현 내에서 super.someMethod()를 호출하여 수퍼클래스 버전의 someMethod()를 호출할 수 있습니다.
  • 오버라이딩된 속성 someProperty는 오버라이딩 getter나 setter 구현 내에서 super.someProperty로 수퍼클래스 버전의 someProperty에 접근할 수 있습니다.
  • 오버라이딩된 서브스크립트 someIndex는 오버라이딩 서브스크립트 구현 내에서 super[someIndex]로 같은 서브스크립트의 수퍼클래스 버전에 접근할 수 있습니다.

메서드 오버라이딩하기

서브클래스 내에서 상속된 인스턴스 메서드나 타입 메서드를 오버라이딩하여 맞춤형 또는 대체 구현을 제공할 수 있습니다.

다음 예제는 Vehicle의 새로운 서브클래스 Train을 정의하고, TrainVehicle에서 상속받은 makeNoise() 메서드를 오버라이딩합니다:

class Train: Vehicle {
    override func makeNoise() {
        print("Choo Choo")
    }
}
swift

Train의 새 인스턴스를 생성하고 makeNoise() 메서드를 호출하면, Train 서브클래스 버전의 메서드가 호출되는 것을 볼 수 있습니다:

let train = Train()
train.makeNoise()
// "Choo Choo" 출력
swift

속성 오버라이딩하기

상속된 인스턴스 속성이나 타입 속성을 오버라이딩하여 자신만의 사용자 정의 getter와 setter를 제공하거나, 오버라이딩 속성이 기본 속성 값이 변경되는 것을 관찰할 수 있도록 속성 옵저버를 추가할 수 있습니다.

속성 Getters와 Setters 오버라이딩하기

상속된 속성이 원본에서 저장 속성으로 구현되었든 계산 속성으로 구현되었든 상관없이 어떤 상속된 속성이라도 오버라이딩하여 자신만의 사용자 정의 getter(및 적절한 경우 setter)를 제공할 수 있습니다. 서브클래스는 상속된 속성의 저장 또는 계산 특성을 모릅니다. 단지 상속된 속성에 특정 이름과 타입이 있다는 것만 알죠. 오버라이딩하는 속성의 이름과 타입을 항상 명시해야 컴파일러가 오버라이드가 같은 이름과 타입의 수퍼클래스 속성과 일치하는지 확인할 수 있습니다.

서브클래스 속성 오버라이드에서 getter와 setter를 모두 제공함으로써 상속된 읽기 전용 속성을 읽기-쓰기 속성으로 표현할 수 있습니다. 그러나 상속된 읽기-쓰기 속성을 읽기 전용 속성으로 표현할 수는 없습니다.

다음 예제는 Vehicle의 서브클래스인 새로운 클래스 Car를 정의합니다. Car 클래스는 기본 정수 값이 1gear라는 새로운 저장 속성을 도입하죠. Car 클래스는 또한 Vehicle에서 상속받은 description 속성을 오버라이딩하여 현재 기어를 포함한 사용자 정의 설명을 제공합니다:

class Car: Vehicle {
    var gear = 1
    override var description: String {
        return super.description + " in gear \(gear)"
    }
}
swift

description 속성의 오버라이드는 super.description을 호출하는 것으로 시작하는데, 이는 Vehicle 클래스의 description 속성을 반환합니다. 그런 다음 Car 클래스 버전의 description은 현재 기어에 대한 정보를 제공하기 위해 이 설명 끝에 약간의 추가 텍스트를 덧붙입니다.

Car 클래스의 인스턴스를 생성하고 gearcurrentSpeed 속성을 설정하면, description 속성이 Car 클래스 내에 정의된 맞춤형 설명을 반환하는 것을 볼 수 있습니다:

let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")
// Car: traveling at 25.0 miles per hour in gear 3
swift

속성 옵저버 오버라이딩하기

속성 오버라이딩을 사용하여 상속된 속성에 속성 옵저버를 추가할 수 있습니다. 이를 통해 해당 속성이 원래 어떻게 구현되었든 상관없이 상속된 속성의 값이 변경될 때 통지받을 수 있습니다. 속성 옵저버에 대한 자세한 내용은 속성 옵저버를 참조하세요.

다음 예제는 Car의 서브클래스인 새로운 클래스 AutomaticCar를 정의합니다. AutomaticCar 클래스는 현재 속도에 따라 자동으로 적절한 기어를 선택하는 자동 변속기가 있는 차를 나타냅니다:

class AutomaticCar: Car {
    override var currentSpeed: Double {
        didSet {
            gear = Int(currentSpeed / 10.0) + 1
        }
    }
}
swift

AutomaticCar 인스턴스의 currentSpeed 속성을 설정할 때마다, 속성의 didSet 옵저버는 새로운 속도에 적합한 기어를 선택하여 인스턴스의 gear 속성을 설정합니다. 구체적으로, 속성 옵저버는 새로운 currentSpeed 값을 10으로 나누고, 가장 가까운 정수로 내림한 다음 1을 더한 기어를 선택합니다. 속도가 35.0이면 기어는 4가 됩니다:

let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
// AutomaticCar: traveling at 35.0 miles per hour in gear 4
swift

이렇게 오버라이딩을 통해 상속받은 특성을 재정의하고 필요에 맞게 변경할 수 있습니다. 오버라이딩은 상속의 유연성을 더해주는 강력한 기능이에요!