[Swift] 상속

HongDuHyeon·2023년 4월 2일
0
post-thumbnail
주말에 회사 나오는게 왜이리 마음이 편할까

상속

일반적으로 부모가 자식에게 재산을 물려주는 행위라고 한다.
클래스가 다른 클래스로부터 매서드, 프로퍼티 또는 다른 특성들을 상속 받는 걸 얘기한다.

상속 받는 클래스를 자식 클래스, 서브 클래스라고들 하며
상속 하는 클래스를 부모 클래스, 슈퍼 클래스라고 한다.

예제

먼저 Vehicle 클래스를 만들고 안에 초기 값을 넣어놓는 코드를 짜봤다.

class Vehicle {
    var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpped) miles per hour"
    }
    func makeNoise_() {
        
    }
}

그리고 Vehicle 클래스를 변수에 담아준 뒤 안에 있는 currentSpeed 프로퍼티의 값을 조회해보고 변경을 한다.

class Bicycle: Vehicle {
    var hasBasket = false
}

Bicycle을 호출했을때 hasBasket 밖에 없을 것 같지만 Vehicle이라는 부모 클래스를 선언했기 떄문에 부모에 있는 프로퍼티, 매서드들 또한 변경,호출이 가능하다.

var bicycle = Bicycle()

bicycle.currentSpeed // 0
bicycle.currentSpeed = 15.0 // 15
bicycle.description // return "traveling at 15.0 miles per hour"

override

서브 클래스는 슈퍼클래스에서 정의된 매소드 프로퍼티 서브스크립등 그대로 사용하지 않고 자신만의 기능으로 사용할 수 있다.

만약 같은 이름의 정의가 슈퍼 클래스에 없는데 오버라이드 키워드를 사용하면 컴파일 과정에서 에러가 나게 되고 실수를 방지할 수 있다.

또한 슈퍼클래스의 동일한 이름의 정의가 있는 오버라이드를 사용하지 않으면 에러가 나게된다.

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

let train = Train()
train.makeNoise()

// choo choo

super

만약 서브클래스에서 슈퍼클래스의 특성을 재정의 했을 때 슈퍼클래스의 특성을 서브클래스에서 사용하고 싶다면 어떻게 해야할까?

super 키워드를 사용하면 된다.

위에서 작성한 코드에서 Vehicle 클래스에 있는 makeNoise 매서드가 먼저 실행되게 하고 싶다면 super 키워드를 사용하면 된다.

class Vehicle {
    var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    func makeNoise() {
        print("speaker on")
    }
}

class Train: Vehicle {
    override func makeNoise() {
        super.makeNoise()
        print("choo choo")
    }
}

let train = Train()
train.makeNoise()

// speaker on
// choo choo

서브클래스에서 특성을 재정의했지만 때에 따라 슈퍼 클래스의 특성을 활용하고 싶을떄 super 키워드를 사용하면 된다.

property override

매서드와 마찬가지로 슈퍼 클래스로 부터 상속받은 인스턴스 프로퍼티나 타입 프로퍼티를 서브 클래스의 용도에 맞게 재정의 할 수 있다.
프로퍼티를 재정의한다는 것은 프로퍼티 자체가 아니라 getter setter observer등을 재정의 한다고 보면 된다.

지금까지 작성한 코드를 활용해서 차가 몇으로 달리고 몇단 기어인지 간단히 확인해보는 코드를 작성해보자.

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

let car = Car()

car.currentSpeed = 30.0
car.gear = 2
print(car.description)

// traveling at 30.0 miles per hour in gear 2

property observer

프로퍼티의 값이 변화되면 그 값이 변화함에 따라서 보여줄 수 있는 코드를 작성해보겠다.

didSet을 사용해서 currentSpeed값이 변하면 변화된 값에 기어를 계산하여 계산된 값을 대입시킨다.

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

let automatic = automaticCar()

automatic.currentSpeed = 35.0

print("AutomaticCar: \(automatic.description)")

// AutomaticCar: traveling at 35.0 miles per hour in gear 4

프로퍼티 재정의를 통해 currentSpeed의 값이 변하면 property observer를 통해 gear 값이 변경되게 사용할 수 있다.

final

만약에 매서드 프로퍼티 타입프로퍼티에 override를 막고자한다면 ?
키워드 앞에 final을 작성하면 override를 막을 수 있다.

class Vehicle {
    final var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    func makeNoise() {
        print("speaker on")
    }
}

이렇게 여러군데에서 사용된 currentSpeed 앞에 final을 적게 되면 아래와 같이 나오게 되어 override를 하지 못하게 된다.

이건 일반적으로 클래스를 만들때도 똑같이 적용된다.
클래스 키워드 앞에 final을 작성하면 해당 클래스를 슈퍼클래스로 하는 서브클래스를 만들 수 없다.

profile
마음이 시키는 프론트엔드.. RN과 IOS를 곁들인..

0개의 댓글