web-dev-qa-db-ja.com

Swiftプロトコルでクラス関数を宣言する

次の混乱がありました。メソッドを宣言するときのstaticキーワードとclassキーワードの主な違いは、サブクラスで2番目のキーワードをオーバーライドできることです。

問題

しかし、Swift 1.2でこのようにプロトコルを宣言すると、

protocol MyProtocol
{
    class func dummyClassMethod()
}

コンパイラはエラーを出します:

クラスメソッドはクラス内でのみ許可されます。 'static'を使用して静的メソッドを宣言する

明らかにMyProtocolはクラスではないため、エラーはかなり説明的ですが、クラスの機能をプロトコルの一部にしたいと考えています。

私が試したこと

プロトコルのインターフェイスをstaticとして宣言すると、コンパイラは満足し、このプロトコルを採用するすべてのクラスでこの静的メソッドを使用できることがわかりました。

protocol MyProtocol
{
    static func dummyClassMethod()
}

質問

だから私の質問は基本的にこれは正しいですか?この宣言は、クラスメソッドを子でオーバーライドできないことを示していますが、私の実装では、次のように記述して使用できます。

class ClassA: MyProtocol
{
    class func dummyClassMethod() {

    }
}

class ClassB: ClassA
{
    override class func dummyClassMethod() {

    }
}

そして今私のダミークラスメソッドはもう静的ではありません...

  1. コンパイラはOkであり、すべてが機能しますが、なぜですか?

  2. インターフェース自体が静的であるという事実に固有ですか?それは実装ではありませんか?

  3. プロトコルのクラスfuncのより良い代替手段はありますか?

Objective-Cソリューション

ObjCでは、これは非常に簡単で、コンパイルして完全に実行できます。

@protocol MyProtocol 

+(void)dummyClassMethod;

@end
30
hris.to

Appleのドキュメント (サブセクションメソッド要件)を確認できます。

そこには言う:

タイププロパティの要件と同様に、プロトコルで定義されている場合、タイプメソッドの要件の前には常にstaticキーワードを付けます。これは、タイプメソッドの要件の前にclassまたはstaticクラスによって実装される場合のキーワード

実際には、次のように実行できます。

最初に、プロトコルを宣言します:

protocol SomeProtocol {
    static func someMethod()
}

次に、あなたのclassには2つのオプションがあります

最初:

class SomeClass : SomeProtocol {
    class func someMethod()
}

2番目:

class SomeClass : SomeProtocol {
    static func someMethod()
}

私はこれがあなたの疑いを明らかにすることを望みます。

30
eMdOS

https://developer.Apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html

プロトコルは、特定のタスクまたは機能の一部に適合するメソッド、プロパティ、およびその他の要件の青写真を定義します。 プロトコルは実際にはこれらの要件のいずれかの実装を提供していません。実装がどのように見えるかを記述するだけです。プロトコルはクラス、構造、または列挙によって採用され、これらの要件の実際の実装を提供します。

このプロトコル定義の後、次のことが合理的になります。

タイププロパティの要件と同様に、タイプメソッドの要件は、プロトコルで定義するときに常にstaticキーワードを前に付けます。これは、クラスによって実装されるときに型メソッドの要件の前にクラスまたは静的キーワードが付けられていても当てはまります...

2
ilya

プロトコルメソッドを静的にして最終的にstaticキーワードでそのメソッドを実装するには

class ClassA: MyProtocol{

    static func dummyClassMethod() {

    }
} 

そして今、あなたはもはやdummyClassMethod関数をオーバーライドすることができません。オーバーライドのみを防止したい場合は、プロトコルメソッドをfinalとして宣言する必要があります。クラス関数については、Swift 1.0では完全にサポートされていませんでしたが、現在Swift 1.2ではサポートされています。静的関数に移行していると思います

1
Zell B.