상속 (Inheritance)

클래스는 다른 클래스에서 메서드, 속성 및 기타 특성을 상속 할 수 있습니다. 한 클래스가 다른 클래스에서 상속 될 때 상속하는 클래스를 하위 클래스라고하고 상속 된 클래스를 수퍼 클래스라고합니다. 상속은 Swift의 다른 유형과 클래스를 구별하는 기본적인 동작입니다.

Swift의 클래스는 수퍼 클래스에 속하는 메서드, 속성 및 첨자를 호출하고 액세스 할 수 있으며 해당 메서드, 속성 및 첨자의 자체 재정의 버전을 제공하여 동작을 수정하거나 수정할 수 있습니다. Swift는 재정의에 일치하는 슈퍼 클래스 정의가 있는지 확인하여 재정의가 올바른지 확인하는 데 도움이됩니다.

클래스는 프로퍼티 값이 변경 될 때 알림을 받기 위해 상속 된 프로퍼티에 프로퍼티 관찰자를 추가 할 수도 있습니다. 프로퍼티 관찰자는 원래 저장된 속성 또는 계산 된 속성으로 정의되었는지 여부에 관계없이 모든 프로퍼티에 추가 할 수 있습니다.

Defining a Base Class
기본 클래스 정의

다른 클래스에서 상속되지 않는 모든 클래스를 기본 클래스라고합니다.

NOTE
Swift 클래스는 범용 기본 클래스에서 상속되지 않습니다. 수퍼 클래스를 지정하지 않고 정의한 클래스는 자동으로 빌드 할 기본 클래스가됩니다.

아래 예제는 Vehicle이라는 기본 클래스를 정의합니다. 이 기본 클래스는 기본값 0.0 (Double의 속성 유형 유추)을 사용하여 currentSpeed라는 프로퍼티를 정의합니다. currentSpeed 프로퍼티의 값은 description이라는 읽기 전용 계산 문자열 프로퍼티에서 차량에 대한 설명을 만드는 데 사용됩니다.

Vehicle 기본 클래스는 makeNoise라는 메서드도 정의합니다. 이 메서드는 실제로 기본 Vehicle 인스턴스에 대해 아무것도 수행하지 않지만 나중에 Vehicle의 하위 클래스에 의해 사용자 정의됩니다.

class Vehicle {
    var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    func makeNoise() {
        // 아무것도하지 않음-임의의 차량이 반드시 소음을내는 것은 아닙니다.
    }
}

이니셜 라이저 구문을 사용하여 Vehicle의 새 인스턴스를 생성합니다.이 인스턴스는 유형 이름 뒤에 빈 괄호가 오는 형식으로 작성됩니다.

let someVehicle = Vehicle()

새 Vehicle 인스턴스를 만든 후 description 프로퍼티에 액세스하여 차량의 현재 속도에 대한 사람이 읽을 수있는 설명을 출력 할 수 있습니다.

print("Vehicle: \(someVehicle.description)")
// 차량 : 시속 0.0 마일로 이동

Vehicle 클래스는 임의의 차량에 대한 공통 특성을 정의하지만 그 자체로는 많이 사용되지 않습니다. 더 유용하게 만들려면 더 구체적인 차량 종류를 설명하도록 수정해야합니다.

Subclassing
서브클래싱

서브 클래 싱은 기존 클래스를 기반으로 새 클래스를 만드는 작업입니다. 하위 클래스는 기존 클래스의 특성을 상속하므로이를 세분화 할 수 있습니다. 하위 클래스에 새 특성을 추가 할 수도 있습니다.

서브 클래스에 수퍼 클래스가 있음을 나타내려면 콜론으로 구분하여 수퍼 클래스 이름 앞에 서브 클래스 이름을 작성하십시오.

class SomeSubclass: SomeSuperclass {
    // 하위 클래스 정의는 여기에
}

다음 예제는 Vehicle의 슈퍼 클래스가 있는 Bicycle이라는 서브 클래스를 정의합니다.

class Bicycle: Vehicle {
    var hasBasket = false
}

새로운 Bicycle 클래스는 currentSpeed 및 description 프로퍼티와 makeNoise() 메서드와 같은 Vehicle의 모든 특성을 자동으로 얻습니다.

상속되는 특성 외에도 Bicycle 클래스는 기본값 인 false (속성에 대한 Bool 유형 유추)를 사용하여 새 저장된 속성 인 hasBasket을 정의합니다.

기본적으로 생성 한 새 Bicycle 인스턴스에는 바구니가 없습니다. 해당 인스턴스가 생성 된 후 특정 Bicycle 인스턴스에 대해 hasBasket 속성을 true로 설정할 수 있습니다.

let bicycle = Bicycle()
bicycle.hasBasket = true

Bicycle 인스턴스의 상속 된 currentSpeed 프로퍼티를 수정하고 인스턴스의 상속 된 description 속성을 쿼리 할 수도 있습니다.

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

하위 클래스는 자체적으로 하위 클래스가 될 수 있습니다. 다음 예제에서는 “tandem”으로 알려진 2 인승 자전거에 대한 Bicycle의 하위 클래스를 만듭니다.

class Tandem: Bicycle {
    var currentNumberOfPassengers = 0
}

Tandem은 Bicycle의 모든 속성과 메서드를 상속하고, 차례로 Vehicle의 모든 속성과 메서드를 상속합니다. Tandem 하위 클래스는 또한 기본값이 0 인 currentNumberOfPassengers라는 새 저장된 속성을 추가합니다.

Tandem의 인스턴스를 생성하면 새로운 속성과 상속 된 속성을 사용하여 작업 할 수 있으며 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
오버라이딩

하위 클래스는 상위 클래스에서 상속 할 인스턴스 메서드, 형식 메서드, 인스턴스 속성, 형식 속성 또는 아래 첨자의 자체 사용자 지정 구현을 제공 할 수 있습니다. 이를 overriding이라고합니다.

상속 될 특성을 재정의하려면 재정의 정의 앞에 override 키워드를 추가합니다. 이렇게하면 재정의를 제공 할 의향이 있고 실수로 일치하는 정의를 제공하지 않았 음을 명확히합니다. 실수로 재정의하면 예기치 않은 동작이 발생할 수 있으며 override 키워드가없는 재정의는 코드가 컴파일 될 때 오류로 진단됩니다.

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

Accessing Superclass Methods, Properties, and Subscripts
수퍼 클래스 메서드, 속성 및 첨자에 액세스

하위 클래스에 대한 메서드, 속성 또는 아래 첨자 재정의를 제공 할 때 재정의의 일부로 기존 슈퍼 클래스 구현을 사용하는 것이 유용한 경우가 있습니다. 예를 들어 기존 구현의 동작을 구체화하거나 기존 상속 변수에 수정 된 값을 저장할 수 있습니다.

이것이 적절한 경우 super 접두사를 사용하여 메서드, 속성 또는 아래 첨자의 슈퍼 클래스 버전에 액세스합니다.

  • someMethod()라는 재정의 된 메서드는 재정의 메서드 구현 내에서 super.someMethod()를 호출하여 someMethod()의 수퍼 클래스 버전을 호출 할 수 있습니다.
  • someProperty라는 재정의 된 속성은 재정의하는 getter 또는 setter 구현 내에서 super.someProperty로 someProperty의 수퍼 클래스 버전에 액세스 할 수 있습니다.
  • someIndex에 대한 재정의 된 첨자는 재정의하는 첨자 구현 내에서 super[someIndex]와 동일한 첨자의 수퍼 클래스 버전에 액세스 할 수 있습니다.

Overriding Methods
오버라이딩 메서드

상속 된 인스턴스 또는 타입 메서드를 재정의하여 하위 클래스 내에서 메서드의 맞춤형 또는 대체 구현을 제공 할 수 있습니다.

다음 예제에서는 Train이 Vehicle에서 상속하는 makeNoise() 메서드를 재정의하는 Train이라는 Vehicle의 새 하위 클래스를 정의합니다.

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

Train의 새 인스턴스를 만들고 makeNoise() 메서드를 호출하면 해당 메서드의 Train 하위 클래스 버전이 호출되는 것을 확인할 수 있습니다.

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

Overriding Properties
오버라이딩 프로퍼티

상속 된 인스턴스 또는 유형 속성을 재정의하여 해당 속성에 대한 고유한 사용자 정의 getter 및 setter를 제공하거나 재정의 속성이 기본 속성 값이 변경 될 때 관찰 할 수 있도록 속성 관찰자를 추가 할 수 있습니다.

Overriding Property Getters and Setters
속성 Getter 및 Setter 재정의

상속 된 속성이 소스에서 저장된 속성 또는 계산 된 속성으로 구현되는지 여부에 관계없이 상속 된 속성을 재정의하기 위해 사용자 지정 getter (및 적절한 경우 setter)를 제공 할 수 있습니다. 상속 된 속성의 저장 또는 계산 된 특성은 하위 클래스에서 알 수 없으며 상속 된 속성에 특정 이름과 유형이 있다는 것만 알고 있습니다. 컴파일러가 재정의가 동일한 이름 및 유형의 수퍼 클래스 속성과 일치하는지 확인할 수 있도록 항상 재정의하는 속성의 이름과 유형을 모두 명시해야합니다.

하위 클래스 속성 재정의에 getter와 setter를 모두 제공하여 상속 된 읽기 전용 속성을 읽기-쓰기 속성으로 표시 할 수 있습니다. 그러나 상속 된 읽기-쓰기 속성을 읽기 전용 속성으로 표시 할 수 없습니다.

NOTE
속성 재정의의 일부로 setter를 제공하는 경우 해당 재정의에 대한 getter도 제공해야합니다. 재정의하는 getter 내에서 상속 된 속성의 값을 수정하지 않으려면 getter에서 super.someProperty를 반환하여 상속 된 값을 전달하면됩니다. 여기서 someProperty는 재정의하는 속성의 이름입니다.

다음 예제는 Vehicle의 하위 클래스인 Car라는 새 클래스를 정의합니다. Car 클래스는 기본 정수 값이 1 인 gear라는 새  프로퍼티를 도입합니다. Car 클래스는 현재 기어를 포함하는 사용자 지정 description을 제공하기 위해 Vehicle에서 상속 한 설명 속성도 재정의합니다.

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

description 속성의 재정의는 Vehicle 클래스의 description 속성을 반환하는 super.description을 호출하여 시작됩니다. 그런 다음 Car 클래스의 설명 버전은 현재 장비에 대한 정보를 제공하기 위해이 설명 끝에 추가 텍스트를 추가합니다.

Car 클래스의 인스턴스를 만들고 해당 gear 및 currentSpeed 속성을 설정하면 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

Overriding Property Observers
오버라이딩 프로퍼티 옵져버

프로퍼티 재정의를 사용하여 상속 된 프로퍼티에 프로퍼티 관찰자를 추가 할 수 있습니다. 이를 통해 상속 된 프로퍼티의 값이 원래 구현 된 방법에 관계없이 변경 될 때 알림을받을 수 있습니다. 프로퍼티 관찰자에 대한 자세한 내용은 속성 관찰자[Property Observers.]를 참조하십시오.

NOTE
상속 된 상수 프로퍼티 또는 상속 된 읽기 전용 계산 프로퍼티에는 프로퍼티 관찰자를 추가 할 수 없습니다. 이러한 프로퍼티의 값은 설정할 수 없으므로 재정의의 일부로 willSet 또는 didSet 구현을 제공하는 것은 적절하지 않습니다.
또한 동일한 프로퍼티에 대해 재정의 setter와 재정의 프로퍼티 관찰자를 모두 제공 할 수는 없습니다. 속성 값의 변경 사항을 관찰하고 싶고 해당 속성에 대한 사용자 지정 setter를 이미 제공하고있는 경우 사용자 지정 setter 내에서 값 변경 사항을 간단히 관찰 할 수 있습니다.

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

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

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

Preventing Overrides
재정의 방지

메서드, 속성 또는 아래 첨자를 final로 표시하여 재정의되는 것을 방지 할 수 있습니다. 메서드, 속성 또는 아래 첨자의 소개 자 키워드 (예 : final var, final func, final class func 및 final subscript) 앞에 final 수정자를 작성하여이를 수행합니다.

하위 클래스에서 final 메서드, 프로퍼티 또는 아래 첨자를 재정의하려는 모든 시도는 컴파일 타임 오류로보고됩니다. 익스텐션의 클래스에 추가하는 메서드, 프로퍼티 또는 아래 첨자는 익스텐션 정의 내에서 최종으로 표시 될 수도 있습니다.

클래스 정의 (final class)에서 class 키워드 앞에 final 수정자를 작성하여 전체 클래스를 final로 표시 할 수 있습니다. 최종 클래스를 서브 클래 싱하려는 모든 시도는 컴파일 타임 오류로보고됩니다.

에 발행했습니다
SWIFT(으)로 분류되었습니다

aaron님이 작성

아무것도 안해도 시간은 흐른다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다