Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

개발자의 삽질

[Swift] Inheritance 본문

Swift

[Swift] Inheritance

uniqueimaginate 2022. 1. 12. 15:00

https://docs.swift.org/swift-book/LanguageGuide/Inheritance.html

 

Inheritance — The Swift Programming Language (Swift 5.5)

Inheritance A class can inherit methods, properties, and other characteristics from another class. When one class inherits from another, the inheriting class is known as a subclass, and the class it inherits from is known as its superclass. Inheritance is

docs.swift.org


오늘은 Inheritance에 대해 알아보자

클래스는 메서드, 프로퍼티 또는 다른 클래스의 다른 특징들을 상속 할 수 있다. 어떤 클래스(A)가 다른 클래스(B)를 상속받는다면, 상속받게 되는 클래스(A)는 Subclass 가 되고 상속하는 클래스(B)를 SuperClass가 된다. 

Defining a 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
    }
}


let someVehicle = Vehicle()

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

Subclassing

SubClassing 이란 기존에 있던 클래스를 기반으로 새로운 클래스를 만드는 것이다. 서브 클래스는 기존의 클래스가 갖고 있는 수정 가능한 특성들을 갖게 된다. 또한, 새로운 특성들을 추가할 수 있다.

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

class Bicycle: Vehicle {
    var hasBasket = false
}

let bicycle = Bicycle()
bicycle.hasBasket = true

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

Bicycle 은 Vehicle 이 가진 특성들(currentSpeed, description 프로퍼티, makeNoise() 메서드)을 갖고 있다.

또한 추가적으로 hasBasket 프로퍼티를 가진다.

class Tandem: Bicycle {
    var currentNumberOfPassengers = 0
}

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

Tandem 인스턴스를 생성하면, 자신이 가진 새로운 프로퍼티와 상속받은 프로퍼티 모두를 갖게 된다.

Overriding

서브 클래스는 슈퍼 클래스가 상속해준 것이 아니라면 자기 자신이 구현한 인스턴스 메서드, 타입 메서드, 인스턴스 프로퍼티, 타입 프로퍼티, 서브스크립트를 가질 수 있다. 만약 슈퍼클래스에서 상속받은 특성들을 재정의 하고 싶다면 override 키워드를 이용해서 재정의가 가능하다. 스위프트 컴파일러는 override 키워드를 보게 되면 기존에 정의된 것을 재정의하는 것인지 확인하게 된다.

Accessing Superclass Methods, Properties, and Subscripts

슈퍼클래스의 것을 재정의하더라도 여전히 슈퍼클래스의 것을 쓰고 싶을 때가 있다.

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

  • 재정의된 메서드 someMethod() 는 슈퍼클래스의 someMethod()를 부르기 위해서 super.someMethod() 를 사용하면 된다.
  • 재정의된 프로퍼티 someProperty() 는 슈퍼클래스의 someProperty()를 부르기 위해서 super.someProperty() 를 사용하면 된다.
  • 재정의된 서브스크립트 someIndex 는 슈퍼클래스의 같은 서브스크립트를 부르기 위해 super[someIndex] 를 사용하면 된다.

Overriding Methods

상속받은 인스턴스나 타입 메소드를 재정의할 수 있다.

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

let train = Train()
train.makeNoise()
// Prints "Choo Choo"

Overriding Properties

상속받은 인스턴스나 타입 프로퍼티를 재정의해서 프로퍼티에 대한 커스텀 getter와 setter를 제공할 수 있고, 프로퍼티 observer 를 추가해서 재정의하는 프로퍼티가 observe 할 수 있게 한다.

 

Overriding Property Getters and Setters

상속받은 프로퍼티가 stored 프로퍼티이든 computed 프로퍼티이든 상관 없이, 재정의하는 프로퍼티에 커스텀 getter(setter)를 설정할 수 있다. 상속받을 때, 서브 클래스는 상속받는 프로터티가 store 또는 computed 속성을 갖는지 알 수 없다. 서브 클래스는 오직 이름과 타입만을 알 뿐이다. 따라서 재정의 할 때, 반드시 이름과 타입을 명시해야 한다. 이렇게 하는 이유는 컴파일러가 슈퍼클래스의 프로퍼티에 재정의하게 되는 프로퍼티가 있는지 이름과 타입으로 확인하기 때문이다.

read-only 프로퍼티를 상속받을 때는 getter와 setter를 제공함으로서 read-write 프로퍼티로 재정의 할 수 있다.

그러나 read-write 프로퍼티를 상속 받을 때는 read-only 프로퍼티로 재정의 할 수 없다.

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

상속받은 프로퍼티에 프로퍼티 observer 를 추가하기 위해 재정의를 할 수 있다. 이렇게 하면 기존에 프로퍼티가 어떻게 구현되어 있는지와 상관없이 상속받은 프로퍼티의 값이 변할 때 알려주게 된다. 

상속받은 constant stored 프로퍼티와 read-only computed 프로퍼티에는 프로퍼티 observer 를 추가할 수 없다!
또한, 하나의 프로퍼티에 setter 와 프로퍼티 observer 를 모두 재정의 하는 것은 불가능하다!
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 var, final func, final class func, final subscript

이렇게 설정해 두면, 서브클래스에서 재정의하려고 할 때 컴파일 에러를 띄우게 된다.

또한 extension 안에서 메서드, 프로퍼티, 서브크립트를 추가한다면 자동으로 final 이 된다.

클래스 전체를 final 로 만들고 싶다면 class 키워드 전에 final 을 붙이면 된다. (final class)

final 클래스를 하위 클래스로 만드려고 하면 컴파일 오류를 띄우게 된다.

Comments