programing

Swift - 하위 클래스에 의해 재정의되어야 하는 클래스 메서드

minimums 2023. 8. 31. 23:44
반응형

Swift - 하위 클래스에 의해 재정의되어야 하는 클래스 메서드

스위프트에서 "순수한 가상 함수"를 만드는 표준 방법이 있습니까? 즉, 모든 하위 클래스에서 재정의되어야 하고 그렇지 않으면 컴파일 시간 오류를 발생시키는 입니까?

두 가지 옵션이 있습니다.

프로토콜 사용

슈퍼클래스를 클래스 대신 프로토콜로 정의

Pro: 각 "하위 클래스"(실제 하위 클래스가 아님)가 필요한 메서드를 구현하는지 여부에 대한 시간 검사 컴파일

단점: "슈퍼클래스"(프로토콜)는 메서드나 속성을 구현할 수 없습니다.

메서드의 수퍼 버전에서 어설

예:

class SuperClass {
    func someFunc() {
        fatalError("Must Override")
    }
}

class Subclass : SuperClass {
    override func someFunc() {
    }
}

찬성: 슈퍼클래스에서 메소드와 속성을 구현할 수 있습니다.

단점: 컴파일 시간 확인 없음

다음은 클래스에서 상속할 수 있고 프로토콜의 컴파일 시간을 확인할 수도 있습니다:)

protocol ViewControllerProtocol {
    func setupViews()
    func setupConstraints()
}

typealias ViewController = ViewControllerClass & ViewControllerProtocol

class ViewControllerClass : UIViewController {

    override func viewDidLoad() {
        self.setup()
    }

    func setup() {
        guard let controller = self as? ViewController else {
            return
        }

        controller.setupViews()
        controller.setupConstraints()
    }

    //.... and implement methods related to UIViewController at will

}

class SubClass : ViewController {

    //-- in case these aren't here... an error will be presented
    func setupViews() { ... }
    func setupConstraints() { ... }

}

추상 클래스/가상 기능은 지원되지 않지만 대부분의 경우 프로토콜을 사용할 수 있습니다.

protocol SomeProtocol {
    func someMethod()
}

class SomeClass: SomeProtocol {
    func someMethod() {}
}

SomeClass가 method를 구현하지 않으면 다음 컴파일 시간 오류가 발생합니다.

error: type 'SomeClass' does not conform to protocol 'SomeProtocol'

"가상" 메서드가 너무 많지 않은 경우에도 하위 클래스가 "구현"을 함수 개체로 기본 클래스 생성자에 전달하도록 하는 것이 또 다른 해결 방법입니다.

class MyVirtual {

    // 'Implementation' provided by subclass
    let fooImpl: (() -> String)

    // Delegates to 'implementation' provided by subclass
    func foo() -> String {
        return fooImpl()
    }

    init(fooImpl: (() -> String)) {
        self.fooImpl = fooImpl
    }
}

class MyImpl: MyVirtual {

    // 'Implementation' for super.foo()
    func myFoo() -> String {
        return "I am foo"
    }

    init() {
        // pass the 'implementation' to the superclass
        super.init(myFoo)
    }
}

여기에 제시된 답변에 따라 프로토콜 대 어설션을 사용할 수 있습니다.drewag그러나 프로토콜에 대한 예제가 없습니다.전 여기서 취재하고 있습니다

의정서

protocol SomeProtocol {
    func someMethod()
}

class SomeClass: SomeProtocol {
    func someMethod() {}
}

이제 모든 하위 클래스는 컴파일 시간에 확인되는 프로토콜을 구현해야 합니다.SomeClass가 method를 구현하지 않으면 다음 컴파일 시간 오류가 발생합니다.

오류: 'SomeClass' 유형이 'SomeProtocol' 프로토콜과 맞지 않습니다.

참고: 이것은 프로토콜을 구현하는 최상위 클래스에서만 작동합니다.모든 하위 클래스는 프로토콜 요구 사항을 무시할 수 있습니다.평한 와 같이memmons

주장.

class SuperClass {
    func someFunc() {
        fatalError("Must Override")
    }
}

class Subclass : SuperClass {
    override func someFunc() {
    }
}

그러나 어설션은 런타임에서만 작동합니다.

컴파일 타임 오류를 발생시키기 위해 주로 하는 일은 다음과 같습니다.

class SuperClass {}

protocol SuperClassProtocol {
    func someFunc()
}

typealias SuperClassType = SuperClass & SuperClassProtocol


class Subclass: SuperClassType {
    func someFunc() {
        // ...
    }
}

이니셜라이저에 함수를 전달하여 이를 달성할 수 있습니다.

예를들면

open class SuperClass {
    private let abstractFunction: () -> Void

    public init(abstractFunction: @escaping () -> Void) {
        self.abstractFunction = abstractFunction
    }

    public func foo() {
        // ...
        abstractFunction()
    }
}

public class SubClass: SuperClass {
    public init() {
        super.init(
            abstractFunction: {
                print("my implementation")
            } 
        )
    }
}

자체를 매개 변수로 전달하여 확장할 수 있습니다.

open class SuperClass {
    private let abstractFunction: (SuperClass) -> Void

    public init(abstractFunction: @escaping (SuperClass) -> Void) {
        self.abstractFunction = abstractFunction
    }

    public func foo() {
        // ...
        abstractFunction(self)
    }
}

public class SubClass: SuperClass {
    public init() {
        super.init(
            abstractFunction: {
                (_self: SuperClass) in
                let _self: SubClass = _self as! SubClass
                print("my implementation")
            }
        )
    }
}

프로:

  • 각 하위 클래스가 필요한 메서드를 구현하는지 여부에 대한 시간 검사 컴파일
  • 슈퍼클래스에서 메소드와 속성을 구현할 수 있습니다.
  • 메모리 누수가 발생하지 않도록 기능에 자신을 전달할 수 없습니다.

단점:

  • 가장 예쁜 코드는 아닙니다.
  • 수업에 사용할 수 없습니다.required init

iOS 개발을 처음 접하게 된 저는 이것이 언제 구현되었는지 완전히 확신할 수는 없지만, 두 가지 장점을 모두 활용할 수 있는 한 가지 방법은 프로토콜에 대한 확장을 구현하는 것입니다.

protocol ThingsToDo {
    func doThingOne()
}

extension ThingsToDo {
    func doThingTwo() { /* Define code here */}
}

class Person: ThingsToDo {
    func doThingOne() {
        // Already defined in extension
        doThingTwo()
        // Rest of code
    }
}

확장은 일반 프로토콜의 함수가 정의되지 않은 경우에도 컴파일 시간 오류를 제공하는 동안 함수에 대한 기본값을 가질 수 있게 해줍니다.

언급URL : https://stackoverflow.com/questions/24111356/swift-class-method-which-must-be-overridden-by-subclass

반응형