[Swift]13. inheritance(상속)

도윤·2021년 7월 24일
0

Swift

목록 보기
12/21

Inheritance

클래스는 메서드,프로퍼티, 다른 특성들을 다른 클래스로부터 상속받을 수 있다.

  • 상속을 해주는 클래스 : superclass
  • 상속을 받는 클래스 : subclass

상속은 스위프트의 class 이외의 다른 타입의 collection에는 없는 기능이다.

서브클래스는 슈퍼클래스의 메서드,프로퍼티,서브스크립트에 접근할 수 있고 호출도 할 수 있다. 또한 overriding을 통해 서브클래스 자체의 특별한 것으로 만들 수 있다. swift는 서브클래스에서 오버라이딩으로 정의한 것들이 슈퍼클래스에 정의되어 있는지 확인하여 오류를 발견해준다.

클래스는 프로펕티 옵저버를 추가하여 상속된 프로퍼티의 값이 변화를 인지할 수도 있다. 프로퍼티 옵저버는 저장프로퍼티인지 계산프로퍼티인지 관계없이 어떠한 프로퍼티에도 추가될 수 있다.


Defining a Base Class

다른 클래스에 상속받지 않는 클래스를 Base Class라 한다. 즉 슈퍼 클래스를 지정하지 않는 클래스는 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
    }
}

위의 코드가 베이스 클래스를 정의한 예이다. 일반 클래스를 정의하고 상속을 하지 않으면 base class가 된다.


Subclassing

서브 클래스는 클래스의 이름에 콜론(:)을 붙이고 상속받을 슈퍼클래스의 이름을 작성하면 된다.

class SomeSubclass: SomeSuperclass {
    // subclass definition goes here
}

위 base class인 Vehicle 클래스 또한 상속받을 수 있다.

class Bicycle: Vehicle {
    var hasBasket = false
}

Bicycle 클래스가 자동적으로 vehicle의 특성들 모두 접근할 수 있다.

또한 상속된 프로퍼티 currentSpeed를 수정할 수 있다.

bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.description)")
// Bicycle: traveling at 15.0 miles per hour

서브클래스들은 또 다른 클래스의 슈퍼클래스가 될 수도 있다.

class Tandem: Bicycle {
    var currentNumberOfPassengers = 0
}

Tandem은 Bicycle의 속성들을 상속받는 동시에 vehicle클래스도 상속받게 되었다.

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

subclass는 superclass에 정의된 메서드,프로퍼티,서브스크립트를 같은 이름으로 커스텀할 수 있는데 이것을 overriding이라고 한다.
오버라이딩을 하기 위해선 override라는 키워드를 사용해야 한다. 이렇게 하면 만약 같은 이름의 정의가 슈퍼클래스에 없는 경우의 실수를 인지할 수 있다.

만약 슈퍼클래스에 동일한 이름의 정의가 있는데 override 키워드를 사용하지 않으면 오류를 발생하게 된다.

Accessing Superclass Method,Properties, and Subscripts

서브클래스에서 오버라이드를 사용한다면 슈퍼클래스에 이미 존재하는 구현의 일부를 사용하는 것이 편할때가 있다. 만약 존재하는 실행 행위를 재정의하고 수정된 값을 저장하는 경우가 있다.

이런 경우에 super()를 사용하면서 슈퍼클래스의 메서드,프로퍼티,서브스크립트에 접근할 수 있다.

  • override된 someMethod()는 superclass 버전의 someMethod()를 super.someMethod()로 호출할 수 있다.
  • override된 property는 super.someProperty로 superclass 버전의 someProperty에 overriding getter,setter로 접근할 수 있다.
  • override된 subscript 접근하기 위한 someindex는 super[someindex]로 subscript에 접근할 수 있다.

Overriding Methods

상속받은 인스턴스,타입 메서드를 오버라이드하여 서브 클래스에서 자체적인 메서드를 정의할 수 있다.

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

상속받은 makeNoise()메서드를 오버라이드하여 자체 메서드로 작성할 수 있다.

Overriding Properties

상속받은 인스턴스나 타입프로퍼티도 오버라이드할 수 있다. 이때 getter,setter도 만들 수 있고 오버라이드 한 프로퍼팉가 원래의 프로퍼티를 변경하는 것을 감지할 수 있다.

Overriding Property Getters and Setters

계산 프로퍼티든 저장프로퍼티든 상속된 프로퍼티를 오버라이드한 프로퍼티는 getter,setter를 가질 수 있다.이렇게 상속받은 프로퍼티가 저장 프로퍼티인지 계산 프로퍼티인지는 오버라이드 할 때 직접 타입을 정의해줘야한다. 슈퍼클래스에서 read-write로 선언된 프로퍼티를 서브클래스에서 read only로 오버라이드할 순 없다. 하지만 슈퍼클래스에서 read only로 선언된 프로퍼티를 read-write로 오버라이드 할 순 있다

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

description 프로퍼티의 오버라이드는 super.description 호출을 통해 superclass인 Vehicle의 description 프로퍼티를 호출하여 return 하고 있다.

Car class의 description은 뒤에 몇가지의 텍스트를 더하여 리턴하여 새롭게 작성되었다.

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

상속된 프로퍼티에 옵저버 프로퍼티를 더하여 오버라이드할 수 있다. Superclass가 원래 어떻게 실행되는가는 상관없이 상속된 프로퍼티의 값이 변경되면 알려주도록 한다. 상수의 저장 프로퍼티나 read-only 계산 프로퍼티는 프로퍼티 옵저버를 추가할 수 없다. 수정되지 않기 대문에 willSet,didSet 실행을 추가하는 것은 적절하지 않다.오버라이딩 setter와 오버라이딩 프로퍼티 옵저버를 같은 프로퍼티에 정의할 순 없다. 프로퍼티 값의 변화를 관찰하고 싶은데 오버라이딩 setter를 이미 만들었다면 setter 내에서 이를 간단하게 관찰 할 수 있다.

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

인스턴스를 생성하여 currentSpeed 프로퍼티의 값을 변경해주면 프로퍼티 옵서버에 의해 gear 프로퍼티의 값이 변경되게 된다.


Preventing Overrides

final을 표시함으로써 오버라이드되는 것을 막을 수 있다.
final된 프로퍼티,메서드,서브스크립트를 오버라이드하려고 한다면 compile-time error가 발생한다.

0개의 댓글