web-dev-qa-db-ja.com

Swiftのプロトコル指向プログラミングとは何ですか?それはどのような付加価値をもたらしますか?

Apple自身のウェブサイトから:「Swiftのデザインの中心には、2つの信じられないほど強力なアイデアがあります:プロトコル指向プログラミングとファーストクラスの値のセマンティクス」

誰かがプロトコル指向プログラミングとは正確に何を詳述し、それがもたらす付加価値を詳しく説明できますか?

私は this を読み、Swift video でProtocol-Oriented Programmingを視聴しましたが、Objective-Cのバックグラウンドから来たものはまだありませんveryわかりやすい英語の回答と、コードスニペットとObjective-Cとの違いに関する技術的な詳細をお寄せください。

ただone私が使用している混乱の<tableViewDelegate, CustomDelegate> Objective-Cの複数のプロトコルにも準拠できないのではないですか?では、もう一度Swift new?


編集: Protocol-Oriented Views ビデオを参照してください。このビデオはより基本的で、意味のあるユースケースを理解しやすいと思います。 WWDCビデオ自体は少し高度で、より広い幅が必要です。さらに、ここでの答えはやや抽象的なものです。

26
Honey

序文:POPとOOPは相互に排他的ではありません。これらは非常に関連する設計パラダイムです。

OOPよりもPO​​Pの主な側面は、継承よりも 構成)を好むことです これにはいくつかの利点があります。

大規模な継承階層では、祖先クラスtendに(一般化された)機能のほとんどが含まれ、リーフサブクラスは最小限の寄与のみを行います。ここでの問題は、先祖クラスが多くのことをしてしまうことです。たとえば、Carは、ドライブ、貨物の保管、乗客の座席、音楽の再生などを行います。これらはそれぞれまったく異なる多くの機能ですが、それらはすべてCarクラスに分けられます。 CarFerrariToyotaなどのBMWの子孫はすべて、この基本クラスに最小限の変更を加えます。

この結果、コードの再利用が減少します。私のBoomBoxも音楽を再生しますが、車ではありません。 Carから音楽再生機能を継承することはできません。

代わりにSwiftが推奨するのは、これらの大きなモノリシッククラスが小さなコンポーネントの構成に分解されることです。これらのコンポーネントは、より簡単に再利用できます。CarBoomBoxMusicPlayerを使用できます。

Swiftはこれを実現するために複数の機能を提供しますが、最も重要なのはプロトコル拡張です。それらは、プロトコルの実装がその実装クラスから分離して存在することを可能にするので、多くのクラスは単にこのプロトコルを実装し、その機能を即座に得ることができます。

33
Alexander

Objective Cでは、プロトコルはほとんどの言語のインターフェースと同じです。したがって、Objective Cでは、プロトコルの使用は [〜#〜] solid [〜#〜] 原則 "に依存します。抽象化に依存します。具体化に依存しないでください。

Swiftプロトコルは大幅に改善されたため、実際にはインターフェイスとして使用できるため、実際にはクラスに近い(C++の 抽象クラ​​ス など)

Objective Cでは、クラス間で機能を共有する唯一の方法は継承です。そして、唯一のone親クラスを継承できます。 Swiftでも採用できます好きなだけ多くのプロトコル。そしてSwiftのプロトコルはデフォルトのメソッド実装を持つことができるため、完全に機能する 多重継承 。柔軟性の向上、コードの再利用の向上-すばらしい!

結論:

プロトコル指向プログラミングはほとんど[〜#〜] oop [〜#〜]と同じですが、継承だけでなくプロトコルの採用によっても機能を共有することにさらに注意を払っています( 継承を介した構成 )。

C++の抽象クラスは、Swiftのプロトコルに非常に似ていますが、C++が特定のタイプのOOPをサポートしているとは誰も言っていません。したがって、generalPOPは、OOPプログラミングパラダイムについて話す場合のバージョンの1つです。Swiftの場合、POPはOOPの改良バージョンです。

9
Avt

POPで値のタイプについて言及している回答がないことには驚きました。

プロトコル指向プログラミングとは何かを理解するには、オブジェクト指向プログラミングの欠点とは何かを理解する必要があります。

  1. それ(OBJC)の継承は1つだけです。継承の階層が非常に複雑な場合、最下位のクラスには保持する必要のない状態がたくさんある可能性があります。
  2. 参照型のクラスを使用しています。参照型はコードを安全でない可能性があります。例えば変更中の参照型のコレクションを処理しています。

Swiftでのプロトコル指向プログラミングでは:

  1. multipleプロトコルに準拠できます。
  2. クラスだけでなく、structuresおよびenumerationsでも使用できます。
  3. プロトコルに準拠するすべてのタイプに共通機能を提供するプロトコル拡張があります。
  4. 参照型の代わりにvalue typeを使用することを好みます。標準のSwift library here を見てください。型の大部分は値型である構造体です。しかし、これは使用しないという意味ではありませんクラスの場合、状況によっては、クラスを使用する必要があります。

したがって、プロトコル指向プログラミングは、OOP欠点を解決しようとするもう1つのプログラミングパラダイムにすぎません。

8
brianLikeApple

上記の答えに追加

Protocolは、メソッドとプロパティのシグネチャが宣言され、列挙型をサブクラス化するクラス/構造体/列挙型がコントラクトに従う必要があるインターフェイスは、スーパークラスプロトコルで宣言されたすべてのメソッドとプロパティを実装する必要があることを意味します。

プロトコルを使用する理由

クラスは単一の継承を提供し、構造体は継承をサポートしません。したがって、プロトコルが導入されました。

Extensionプロトコル内で宣言されたメソッドを拡張内に実装して、プロトコルが同じメソッド実装を持つ複数のクラス/構造体で継承される場合にコードの冗長性を回避できます。構造体/列挙型のオブジェクトを宣言するだけでメソッドを呼び出すことができます。拡張機能をクラスのリストに制限することもできますが、制限されたクラスのみが拡張機能内に実装されたメソッドを使用できますが、残りのクラスは独自のクラス内にメソッドを実装する必要があります。

protocol validator{

    var id : String{ get }
    func capitialise()-> (String)

}

extension validator where Self : test{
    func capitialise() -> String{
        return id.capitalized
    }
}

class test : validator {

    var id: String

    init(name:String) {
        id = name
    }
}

let t = test(name: "Ankit")
t.capitialise()

使用する場合 In OOP飛行機、自転車、車などに継承される車両基本クラスがあると仮定します。ここでは、加速は3つの中で一般的な方法です。飛行機のflyableメソッドではなく、サブクラスです。したがって、OOPでもflyableメソッドを宣言している場合、bikeとcarのサブクラスにも、それらのクラスには役に立たないflyflyメソッドが継承されています。したがって、POPで2つのプロトコルを宣言できます。は飛行可能なオブジェクト用で、その他はブレークおよび加速メソッド用です。また、飛行可能なプロトコルは飛行機だけが使用できるように制限できます

4
Ankit garg

プロトコル指向プログラミング(POP)

  • Swift 2.0以降
  • クラス(OOP)
    • 参照型です
    • メモリリーク、不正なデータの保存、複雑なマルチスレッド環境でアクセスするための競合状態
    • チェーン時にスーパークラスのメンバーを継承することにより、大きくすることができます
  • 構造体(POP)
    • 値タイプです-必要なときに新しいコピーが作成されるたび
    • 多重継承を提供-プロトコルを継承
    • プロトコル:
    • どのメソッド、プロパティ、初期化が必要かを定義しますo別のプロトコルを継承できます
    • プロトコル関数を実装するためにオーバーライドキーワードを使用する必要はありません
  • 拡張子:
    • プロトコルのデフォルト値とデフォルト実装
    • プロトコルにメンバーを追加できます
0
mehdi parsaei