신속한 상속


상속은 하나의 클래스가 다른 클래스의 메서드와 속성을 획득하는 것으로 이해될 수 있습니다.

클래스가 다른 클래스를 상속할 때 상속받는 클래스를 서브클래스, 상속받은 클래스를 슈퍼클래스(또는 부모 클래스)라고 합니다

Swift에서 클래스는 슈퍼클래스의 메서드, 속성, 서브스크립트를 호출하고 액세스할 수 있습니다. , 그리고 재정의될 수 있습니다.

클래스에 상속된 속성에 대한 속성 관찰자를 추가할 수도 있습니다.


기본 클래스

다른 클래스로부터 상속받지 않는 클래스를 기본 클래스라고 합니다.

다음 예에서는 학생(stname)과 각 과목의 점수(mark1, mark2, mark3)를 설명하는 기본 클래스 StudDetails를 정의합니다.

class StudDetails {
    var stname: String!
    var mark1: Int!
    var mark2: Int!
    var mark3: Int!
    init(stname: String, mark1: Int, mark2: Int, mark3: Int) {
        self.stname = stname
        self.mark1 = mark1
        self.mark2 = mark2
        self.mark3 = mark3
    }
}
let stname = "swift"
let mark1 = 98
let mark2 = 89
let mark3 = 76

print(stname)
print(mark1)
print(mark2)
print(mark3)

위 프로그램 실행의 출력 결과는 다음과 같습니다.

swift
98
89
76
swift
98
89
76

Subclass

Subclassing은 기존 클래스를 기반으로 새로운 클래스를 만드는 것을 말합니다.

특정 클래스의 슈퍼클래스를 지정하려면 서브클래스 이름 뒤에 콜론(:)으로 구분하여 슈퍼클래스 이름을 씁니다. 구문 형식은 다음과 같습니다

class SomeClass: SomeSuperclass {
    // 类的定义
}

다음 예에서는 StudDetails 슈퍼클래스, 그리고 Tom 서브클래스를 사용하여 상속합니다.

class StudDetails
{
    var mark1: Int;
    var mark2: Int;
    
    init(stm1:Int, results stm2:Int)
    {
        mark1 = stm1;
        mark2 = stm2;
    }
    
    func show()
    {
        print("Mark1:\(self.mark1), Mark2:\(self.mark2)")
    }
}

class Tom : StudDetails
{
    init()
    {
        super.init(stm1: 93, results: 89)
    }
}

let tom = Tom()
tom.show()

위 프로그램 실행의 출력 결과는 다음과 같습니다.

Mark1:93, Mark2:89

Overriding

하위 클래스는 상속된 인스턴스 메소드, 클래스 메소드, 인스턴스 속성 또는 서브스크립트를 통해 구현될 수 있습니다. 스크립트 사용자 정의된 기능의 경우 이 동작을 재정의라고 합니다.

재작성을 구현하기 위해 override 키워드를 사용할 수 있습니다.

슈퍼 클래스 메소드, 속성 및 서브스크립트에 액세스

슈퍼 접두사를 사용하여 슈퍼 클래스 메소드, 속성 또는 서브스크립트에 액세스할 수 있습니다.

Override액세스 메서드, 속성, 첨자 스크립트
methodsuper.somemethod()
propertysuper.someProperty()
아래 첨자 스크립트 super[someIndex ]

Override 메서드 및 속성

Override 메서드

하위 클래스에서는 override 키워드를 사용하여 상위 클래스 메서드를 재정의할 수 있습니다.

다음 예에서는 show() 메서드를 다시 작성했습니다.

class SuperClass {
    func show() {
        print("这是超类 SuperClass")
    }
}

class SubClass: SuperClass  {
    override func show() {
        print("这是子类 SubClass")
    }
}

let superClass = SuperClass()
superClass.show()

let subClass = SubClass()
subClass.show()

위 프로그램 실행의 출력 결과는 다음과 같습니다.

这是超类 SuperClass
这是子类 SubClass

속성 다시 쓰기

사용자 정의된 getter(또는 setter)를 제공하여 상속된 모든 항목을 재정의할 수 있습니다. Properties , 상속된 속성이 저장 속성인지 계산 속성인지에 관계없이.

하위 클래스는 상속된 속성이 저장되는지 또는 계산되는지 알지 못합니다. 상속된 속성에 이름과 유형이 있다는 것만 알 수 있습니다. 따라서 속성을 재정의하는 경우 해당 이름과 유형을 작성해야 합니다.

참고:

  • 재정의된 속성에 setter를 제공하는 경우 getter도 제공해야 합니다.

  • 오버라이드된 버전의 getter에서 상속된 속성 값을 수정하지 않으려면 super.someProperty를 통해 상속된 값을 직접 반환할 수 있습니다. 여기서 someProperty는 오버라이드하려는 속성의 이름입니다.

다음 예에서는 슈퍼 클래스 Circle과 하위 클래스 Rectangle을 정의합니다. Rectangle 클래스에서 속성 영역을 다시 작성합니다.

class Circle {
    var radius = 12.5
    var area: String {
        return "矩形半径 \(radius) "
    }
}

// 继承超类 Circle
class Rectangle: Circle {
    var print = 7
    override var area: String {
        return super.area + " ,但现在被重写为 \(print)"
    }
}

let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("Radius \(rect.area)")

위 프로그램 실행의 출력 결과는 다음과 같습니다.

Radius 矩形半径 25.0  ,但现在被重写为 3

관찰자 속성 다시 작성

속성 재정의에서 상속된 속성에 대한 속성 관찰자를 추가할 수 있습니다. 이러한 방식으로 상속된 속성 값이 변경되는 시기를 감지할 수 있습니다.

참고: 상속된 상수 저장 속성이나 상속된 읽기 전용 계산 속성에 대해서는 속성 관찰자를 추가할 수 없습니다.

class Circle {
    var radius = 12.5
    var area: String {
        return "矩形半径为 \(radius) "
    }
}

class Rectangle: Circle {
    var print = 7
    override var area: String {
        return super.area + " ,但现在被重写为 \(print)"
    }
}


let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("半径: \(rect.area)")

class Square: Rectangle {
    override var radius: Double {
        didSet {
            print = Int(radius/5.0)+1
        }
    }
}


let sq = Square()
sq.radius = 100.0
print("半径: \(sq.area)")
半径: 矩形半径为 25.0  ,但现在被重写为 3
半径: 矩形半径为 100.0  ,但现在被重写为 21

재작성 방지

final 키워드를 사용하여 재작성을 방지할 수 있습니다.

최종 메서드, 속성 또는 아래 첨자 스크립트를 재정의하면 컴파일 중에 오류가 보고됩니다.

키워드 클래스 앞에 final 속성(최종 클래스)을 추가하여 전체 클래스를 final로 표시할 수 있습니다. 이러한 클래스는 상속될 수 없습니다. 그렇지 않으면 컴파일 오류가 보고됩니다.

final class Circle {
    final var radius = 12.5
    var area: String {
        return "矩形半径为 \(radius) "
    }
}
class Rectangle: Circle {
    var print = 7
    override var area: String {
        return super.area + " ,但现在被重写为 \(print)"
    }
}

let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("半径: \(rect.area)")

class Square: Rectangle {
    override var radius: Double {
        didSet {
            print = Int(radius/5.0)+1
        }
    }
}

let sq = Square()
sq.radius = 100.0
print("半径: \(sq.area)")

위의 예에서는 final 키워드를 사용하고 다시 쓰기를 허용하지 않으므로 실행 시 오류가 보고됩니다.

error: var overrides a 'final' var
    override var area: String {
                 ^
note: overridden declaration is here
    var area: String {
        ^
error: var overrides a 'final' var
    override var radius: Double {
                 ^
note: overridden declaration is here
    final var radius = 12.5
              ^
error: inheritance from a final class 'Circle'
class Rectangle: Circle {
      ^