본문 바로가기

Swift Language

Swift Language - 12 - 상속 (Inheritance)

기반 클래스 정의 (Defining a Base Class)

// 다른 어떤 클래스로부터도 상속받지 않은 클래스를 기반 클래스라 합니다.
// 예제를 통해 실제 사용에 대해 알아 보겠습니다.
class Vehicle {
    var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    func makeNoise() {
        // do nothing - an arbitrary vehicle doesn't necessarily make a noise
    }
}

print("Vehicle: \(someVehicle.description)")
// Vehicle: traveling at 0.0 miles per hour

 

서브클래싱 (Subclassing)

// 상속, 다시말해 서브클래싱을 하면 부모로 부터 성격을 상속받고 자기 자신 고유의 특성도 추가할 수 있습니다. 
// 서브클래싱해 새 클래스를 선언하는 코드는 다음과 같습니다.
class SomeSubclass: SomeSuperclass {
    // subclass definition goes here
}


// 위 탈것을 서브클래싱해 자전거라는 클래스를 선언하면 코드는 다음과 같습니다.
class Bicycle: Vehicle {
    var hasBasket = false
}


// Bicycle은 Vehicle 서브클래싱하고 자기 자신의 속성 hasBasket도 추가합니다.
let bicycle = Bicycle()
bicycle.hasBasket = true


// Bicycle객체를 생성해 고유 속성을 사용할 수 있는 것을 확인할 수 있습니다.
bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.description)")
// Bicycle: traveling at 15.0 miles per hour


// 물론 부모로부터 물려받은 currentSpeed, description속성도 사용 가능합니다. 
// 서브클래스로 생성된 클래스를 다시 서브클래싱 하는 것도 가능합니다.
class Tandem: Bicycle {
    var currentNumberOfPassengers = 0
}


// Bicycle을 서브클래싱해서 Tandem이라는 클래스를 생성하고 속성도 추가합니다.
let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print("Tandem: \(tandem.description)")
// Tandem: traveling at 22.0 miles per hour

 

오버라이딩 (Overriding)

서브클래스에서는 부모클래스에서 상속받은 것을 재정의 할 수 있습니다. 이것을 overriding 이라 부르는데, 오버라이딩은 인스턴스 메소드, 타입 메소드, 인스턴스 프로퍼티, 타입 프로퍼티, 서브스크립트 모두에 대해 가능합니다. 오버라이드를 위해서는 다른 선언 앞에 override키워드를 붙여줍니다. Swift에서는 이 override키워드를 보면 부모에 그 정의가 있는지 확인합니다.

 

부모클래스의 메소드, 프로퍼티, 서브스크립트의 접근 (Accessing Superclass Methods, Properties, and Subscripts)

super키워드와 점문법 혹은 인덱스 구문으로 부모 클래스의 메소드, 프로퍼티, 서브스크립트에 접근할 수 있습니다. super.someMethodsuper.somePropertysuper[someIndex]

 

메소드 오버라이드 (Overriding Methods)

// 상속받은 메소드를 오버라이드 하기 위해서는 메소드 선언 앞에 override키워드를 붙이고 내용을 적어주면 됩니다.
class Train: Vehicle {
    override func makeNoise() {
        print("Choo Choo")
    }
}

let train = Train()
train.makeNoise()
// Prints "Choo Choo" : 새로 정의한 내용이 출력됩니다.

 

프로퍼티 오버라이드 (Overriding Properties)

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

// 오버라이딩한 프로퍼티가 재정의 한대로 출력되는 것을 확인할 수 있습니다.
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

 

프로퍼티 옵저버 오버라이드 (Overriding Property Observers)

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


// 코드 실행결과 오버라이드한 내용이 출력되는 것을 확인할 수 있습니다.
let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
// AutomaticCar: traveling at 35.0 miles per hour in gear 4

 

오버라이드 방지 (Preventing Overrides)

서브클래스에서 특정 메소드, 프로퍼티, 서브스크립트가 오버라이드 되는 것을 방지하려면 final키워드를 사용합니다. 다시말해, final로 선언되면 override되는 것을 막을 수 있습니다. (final func, final class func, final subscript) 만일 final로 선언된 메소드, 프로퍼티, 서브스크립트를 오버라이드 하려고 하면 컴파일 시간(compile-time)에 에러가 발생합니다. 클래스 전체를 final로 선언해서 클래스 안의 모든 메소드, 프로퍼티 등이 override가 되는 것을 막을 수 있습니다. (final class)