111

Swift で「純粋仮想関数」を作成する標準的な方法はありますか。すべてのサブクラスでオーバーライドする必要があり、そうでない場合、コンパイル時エラーの原因となるのはどれですか?

4

8 に答える 8

173

次の 2 つのオプションがあります。

1.プロトコルを使用する

クラスではなくプロトコルとしてスーパークラスを定義する

Pro:各「サブクラス」(実際のサブクラスではない)が必要なメソッドを実装しているかどうかをコンパイル時にチェックします

短所:「スーパークラス」(プロトコル)はメソッドまたはプロパティを実装できません

2. メソッドのスーパー バージョンでアサートする

例:

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

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

長所:スーパークラスでメソッドとプロパティを実装できます

Con : コンパイル時間チェックなし

于 2014-06-08T22:18:06.330 に答える
35

抽象クラス/仮想関数のサポートはありませんが、ほとんどの場合、おそらくプロトコルを使用できます。

protocol SomeProtocol {
    func someMethod()
}

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

SomeClass が someMethod を実装していない場合、次のコンパイル時エラーが発生します。

error: type 'SomeClass' does not conform to protocol 'SomeProtocol'
于 2014-06-08T22:15:38.950 に答える
0

関数を初期化子に渡すことで実現できます。

例えば

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")
            } 
        )
    }
}

パラメータとして self を渡すことで拡張できます。

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")
            }
        )
    }
}

プロ

  • 各サブクラスが必要なメソッドを実装しているかどうかのコンパイル時間チェック
  • スーパークラスでメソッドとプロパティを実装できます
  • 関数に self を渡すことはできないため、メモリ リークが発生しないことに注意してください。

短所

  • それは最もきれいなコードではありません
  • のクラスには使用できません。required init
于 2020-12-29T12:56:39.463 に答える