2015-05-14 2 views
22

У меня было следующее замешательство. Насколько я знаю, основное различие между статическими и классом ключевых слов при объявлении метода заключается в том, что второй может быть переопределен в подклассах.Swift Объявить класс Func в протоколе

Проблема

Однако, когда я объявляю протокол в Swift 1.2, как это:

protocol MyProtocol 
{ 
    class func dummyClassMethod() 
} 

компилятор выдает ошибку:

Class methods are only allowed within classes; use 'static' to declare a static method

ошибка является довольно описательным, как очевидно, MyProtocol не является классом, однако я хочу сделать часть func класса.

То, что я пытался

Я обнаружил, что если я объявляю интерфейс в протоколе, как статического, компилятор доволен, и я мог бы использовать этот статический метод во всех классах, которые принимают этот протокол:

protocol MyProtocol 
{ 
    static func dummyClassMethod() 
} 

вопрос

Так что мой вопрос, в принципе это правильно? Эта декларация гласит, что мой метод класса не может быть переопределен у детей, однако в моей реализации я мог бы написать и использовать следующее:

class ClassA: MyProtocol 
{ 
    class func dummyClassMethod() { 

    } 
} 

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

    } 
} 

и теперь мой dummyClassMethod не статичен больше ...

  1. Компилятор работает, и все работает, но почему?

  2. Это конкретный факт, что сам интерфейс является статическим, однако это реализация не так ли?

  3. Есть ли лучшая альтернатива классу func в протоколах?

решение Objective-C

В ObjC это довольно легко и компилировать & бесперебойная работа:

@protocol MyProtocol 

+(void)dummyClassMethod; 

@end 
+0

Я знаю, что это не относится к вашему вопросу, а также, но почему вам нужно подклассы? – ilya

+0

Я не на момент написания этого, но кто знает в будущем. Я больше понимаю, как это работает, поэтому я могу правильно его использовать. –

+0

был этот вопрос решающий op? Я новичок в быстроте. – CaffeineShots

ответ

1

Чтобы сделать метод протокола статического и окончательного внедрения этого метода с помощью статического ключевого слова

class ClassA: MyProtocol{ 

    static func dummyClassMethod() { 

    } 
} 

и теперь вы не можете переопределить du Функция mmyClassMethod больше. Если вы хотите предотвратить переопределение только, вы должны объявить метод протокола окончательным. О функциях класса они не были полностью поддерживаются в Swift 1.0 и теперь в Swift 1.2 Я думаю, что они движутся в направлении статических функций

+0

Конечное ключевое слово может использоваться только в классах и классах. Отсюда и проблема с ключевым словом. –

+0

Но все же, если вы реализуете метод протокола как статический, сделайте его статическим и окончательным, и это решит проблему вашей проблемы. –

+0

Ну, ti решит ее на уровне реализации, а не в интерфейсе. Я должен быть уверен, что каждая реализация протокола реализует его как статическую окончательную, а не делает сам интерфейс требующим этого. –

2

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

A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol doesn’t actually provide an implementation for any of these requirements—it only describes what an implementation will look like.The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements.

После этого определения протокола становится разумным, что

As with type property requirements, you always prefix type method requirements with the static keyword when they are defined in a protocol. This is true even though type method requirements are prefixed with the class or static keyword when implemented by a class...

22

Вы можете просмотреть Apple's Documentation (подраздел Метод Требования).

Там говорит:

As with type property requirements, you always prefix type method requirements with the static keyword when they are defined in a protocol. This is true even though type method requirements are prefixed with the class or static keyword when implemented by a class

На практике, вы можете сделать это следующим образом:

Во-первых, объявить протокол:

protocol SomeProtocol { 
    static func someMethod() 
} 

Тогда в вашем class вы» ve 2 опции:

Первое:

class SomeClass : SomeProtocol { 
    class func someMethod() 
} 

Второе:

class SomeClass : SomeProtocol { 
    static func someMethod() 
} 

Я надеюсь, что это может прояснить ваши сомнения ..

+1

Немного странно, что вы можете объявить 'func'' static' в протоколе, но просто игнорируете этот факт и используете его как 'class func'. Тем более, что 'static' подразумевает' final class', а в протоколе func - это ничего, кроме окончательного, поскольку он должен быть реализован. Кто-нибудь знает, почему Apple разработает такой язык? –

+0

@SandyChapman Я думаю, что вы пытаетесь сравнить Swift vs Java, не делайте этого, просто прочитайте Apple Doc, мой ответ основан на этом. Я знаю, что это невозможно в Java, но Swift - это не Java. Многие вещи имеют разные типы поведения, такие как 'private',' public', 'internal',' final', 'static' и т. Д., Просто прочитайте документ. – eMdOS

+2

Нет, я не пытаюсь сравнивать с Java. В Swift 'static' эквивалентно' final class' при использовании в классах, но при использовании в протоколе имеет другое значение. Я говорю, что использование Swift в требовании 'static' в протоколах не имеет смысла, когда вы можете игнорировать неявный' final', который он имеет при переопределении в классе. Было бы разумнее, если бы протоколы требовали использовать 'class', а не' static', поскольку он оставил бы его разработчику, чтобы определить, хотят ли они, чтобы этот метод был «final». –

Смежные вопросы