Swiftのプロトコル拡張からインスタンスメソッドをオーバーライドする方法は?

コリン・マクドネル

プロトコル拡張からインスタンスメソッドをオーバーライドしようとしていますが、問題が発生しています。

コンテキストとして、私はさまざまなUICollectionViewを備えたiOSアプリを作成しています。これらのビューは、さまざまなデータベースからデータを取得し(さまざまなコールバック機能が必要)、レイアウトも大きく異なります。(データベース、レイアウト)の任意の組み合わせが可能であるため、大量のコード重複なしに優れたOOPクラス階層を作成することは困難です。

レイアウト関数(主にUICollectionViewDelegateFlowLayoutプロトコルで定義されているもの)をプロトコル拡張に配置することを考えていたので、特定のUICollectionViewサブクラスを、関連するすべてのレイアウト関数を実装するように拡張されたプロトコルで装飾できますが、苦労していますそれの。問題の本質は、以下のコードに含まれています。

class Base {
    func speak(){
        print("Base")
    }
}

class SubA: Base, ProtocolA {}

class SubB: Base, MyProtocolB {}

protocol MyProtocolA{
    func speak()
}

protocol MyProtocolB{
    func speak()
}

extension MyProtocolA{
    func speak(){
        print("A")        
    }
}

extension MyProtocolA{
    func speak(){
        print("B")        
    }
}

let suba = SubA()
suba.speak()  // prints "Base", I want it to print "A"

let subb = SubB()
subb.speak()  // prints "Base", I want it to print "B"

考え?

ロブ

プロトコルのデフォルトの実装は、これらのプロトコルに準拠するクラスがそのメソッド自体を実装していない場合にのみ呼び出されます。クラスのメソッドは、プロトコルのデフォルトの実装をオーバーライドしますが、その逆ではありません。

通常、次のようなことを行います。

protocol MyProtocolA {
    func speak()
}

protocol MyProtocolB {
    func speak()
}

extension MyProtocolA {
    func speak() {
        print("A")        
    }
}

extension MyProtocolB {
    func speak() {
        print("B")        
    }
}

class SubA: MyProtocolA {}

class SubB: MyProtocolB {}

let suba = SubA()
suba.speak()  // prints "A"

let subb = SubB()
subb.speak()  // prints "B"

しかし、あなたがそうするなら

class SubC: MyProtocolA {
    func speak (){
        print("C")
    }
}

let subc = SubC()
subc.speak()  // prints "C"

率直に言って、これを見るとBase、この例の使用は完全に冗長であるため、削除しました。明らかに、Base他の理由でからサブクラス化する必要がある場合は、お気軽に。ただし、重要な点は、プロトコルのデフォルトの実装がクラスの実装をオーバーライドするのではなく、その逆であるということです。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

クラスを拡張し、インターフェースからのメソッドをオーバーライドする方法は?

分類Dev

小枝の拡張からテンプレートブロックをオーバーライドする方法は?

分類Dev

拡張クラスのメインクラスのメソッドを使用し、コンストラクターループを回避する方法

分類Dev

拡張インターフェースのメソッドとJavaをオーバーライドするActionscript?

分類Dev

コンストラクター内の拡張プロパティをオーバーライドするTypescript

分類Dev

プロトコル拡張インスタンスメソッドから静的変数を読み取る

分類Dev

プロジェクトがVS2013ソリューションの一部である場合、インテリセンスとメインクラスのコードファイルからメソッドのオーバーロードを非表示にする方法は?

分類Dev

D:拡張クラスの不変メソッドをオーバーライドする方法は?

分類Dev

Java。クラスのメソッドをプライベートコンストラクターでオーバーライドする方法

分類Dev

ES6クラスインスタンスのプロパティとメソッドを使用してオブジェクトを拡張する方法

分類Dev

Javaでは、インターフェースのデフォルトメソッドを作成する方法をオーバーライドできませんか?

分類Dev

Pythonのクラスインスタンス化からメソッドをインポートする方法は?

分類Dev

Swiftプロトコルと拡張機能、要件に応じてオーバーライドされたメソッドまたはデフォルトの拡張メソッドを呼び出す必要があります

分類Dev

異なるクラスからオーバーライドする拡張メソッドを作成する

分類Dev

SaveViewState オーバーライド メソッドでカスタム コントロールの可視状態を取得する方法

分類Dev

グローバルスコープガードをコントローラー/メソッドスコープガードでオーバーライドすることは可能ですか?

分類Dev

非ローカルパッケージのインターフェイスメソッドを拡張する

分類Dev

クラスはKotlinまたはJavaでリフレクションを使用して、インターフェイスからデフォルトのメソッドをオーバーライドしているかどうかを確認する方法?

分類Dev

Iterable <interface>の戻り値の型メソッドをIterable <にオーバーライドするにはどうすればよいですか?インターフェイスを拡張>戻り値の型メソッド

分類Dev

implemは抽象的ではなく、インターフェースを拡張する際に抽象メソッドFinalScore()をオーバーライドしません

分類Dev

Objectivecのスーパークラスからプライベートメソッドとプロパティをオーバーライドする方法

分類Dev

インターフェイスから継承されたメソッドを表示するためのVisualStudio2019の拡張機能/プラグイン

分類Dev

オブジェクトインスタンスのメソッドをstd :: functionタイプのコールバックに渡す方法は?

分類Dev

外部ファイルのスコープを維持しながら、プロトタイプ関数を拡張/オーバーライドします

分類Dev

Swift-具象サブクラスの拡張メソッドをオーバーライドするにはどうすればよいですか?

分類Dev

オーバーライドする実装でメソッドのインターフェイスのデフォルト実装を呼び出す方法は?

分類Dev

ジェネリック(Java)を使用する拡張インターフェースでメソッドコントラクトをオーバーライドしますか?

分類Dev

NopCommerceプラグインでコントローラーまたはそのメソッドをオーバーライドする方法は?

分類Dev

コンストラクター内のメソッドでItclオブジェクトを拡張する

Related 関連記事

  1. 1

    クラスを拡張し、インターフェースからのメソッドをオーバーライドする方法は?

  2. 2

    小枝の拡張からテンプレートブロックをオーバーライドする方法は?

  3. 3

    拡張クラスのメインクラスのメソッドを使用し、コンストラクターループを回避する方法

  4. 4

    拡張インターフェースのメソッドとJavaをオーバーライドするActionscript?

  5. 5

    コンストラクター内の拡張プロパティをオーバーライドするTypescript

  6. 6

    プロトコル拡張インスタンスメソッドから静的変数を読み取る

  7. 7

    プロジェクトがVS2013ソリューションの一部である場合、インテリセンスとメインクラスのコードファイルからメソッドのオーバーロードを非表示にする方法は?

  8. 8

    D:拡張クラスの不変メソッドをオーバーライドする方法は?

  9. 9

    Java。クラスのメソッドをプライベートコンストラクターでオーバーライドする方法

  10. 10

    ES6クラスインスタンスのプロパティとメソッドを使用してオブジェクトを拡張する方法

  11. 11

    Javaでは、インターフェースのデフォルトメソッドを作成する方法をオーバーライドできませんか?

  12. 12

    Pythonのクラスインスタンス化からメソッドをインポートする方法は?

  13. 13

    Swiftプロトコルと拡張機能、要件に応じてオーバーライドされたメソッドまたはデフォルトの拡張メソッドを呼び出す必要があります

  14. 14

    異なるクラスからオーバーライドする拡張メソッドを作成する

  15. 15

    SaveViewState オーバーライド メソッドでカスタム コントロールの可視状態を取得する方法

  16. 16

    グローバルスコープガードをコントローラー/メソッドスコープガードでオーバーライドすることは可能ですか?

  17. 17

    非ローカルパッケージのインターフェイスメソッドを拡張する

  18. 18

    クラスはKotlinまたはJavaでリフレクションを使用して、インターフェイスからデフォルトのメソッドをオーバーライドしているかどうかを確認する方法?

  19. 19

    Iterable <interface>の戻り値の型メソッドをIterable <にオーバーライドするにはどうすればよいですか?インターフェイスを拡張>戻り値の型メソッド

  20. 20

    implemは抽象的ではなく、インターフェースを拡張する際に抽象メソッドFinalScore()をオーバーライドしません

  21. 21

    Objectivecのスーパークラスからプライベートメソッドとプロパティをオーバーライドする方法

  22. 22

    インターフェイスから継承されたメソッドを表示するためのVisualStudio2019の拡張機能/プラグイン

  23. 23

    オブジェクトインスタンスのメソッドをstd :: functionタイプのコールバックに渡す方法は?

  24. 24

    外部ファイルのスコープを維持しながら、プロトタイプ関数を拡張/オーバーライドします

  25. 25

    Swift-具象サブクラスの拡張メソッドをオーバーライドするにはどうすればよいですか?

  26. 26

    オーバーライドする実装でメソッドのインターフェイスのデフォルト実装を呼び出す方法は?

  27. 27

    ジェネリック(Java)を使用する拡張インターフェースでメソッドコントラクトをオーバーライドしますか?

  28. 28

    NopCommerceプラグインでコントローラーまたはそのメソッドをオーバーライドする方法は?

  29. 29

    コンストラクター内のメソッドでItclオブジェクトを拡張する

ホットタグ

アーカイブ