Подтвердить что ты не робот

Swift Объявить класс Func в протоколе

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

Проблема

Однако, когда я объявляю протокол в Swift 1.2 следующим образом:

protocol MyProtocol
{
    class func dummyClassMethod()
}

компилятор дает сообщение об ошибке:

Методы класса допускаются только внутри классов; использовать 'static' для объявления статический метод

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

Что я пробовал

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

protocol MyProtocol
{
    static func dummyClassMethod()
}

Вопрос

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

class ClassA: MyProtocol
{
    class func dummyClassMethod() {

    }
}

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

    }
}

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

  • Компилятор работает нормально, и все работает - но почему?

  • Является ли это специфическим для того факта, что сам интерфейс является статическим, однако       это реализация не?

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

Objective-C решение

В ObjC это довольно просто и компилируется и выполняется безупречно:

@protocol MyProtocol 

+(void)dummyClassMethod;

@end
4b9b3361

Ответ 1

Вы можете просмотреть Документацию Apple (требования к подразделу Методы).

Там говорится:

Как и в случае с требованиями к типу типа, вы всегда префиксные требования к типу типа с ключевым словом static, когда они определены в протоколе. Это верно, хотя требования к типу метода имеют префикс с ключевым словом class или static при реализации классом

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

Сначала объявите свой протокол:

protocol SomeProtocol {
    static func someMethod()
}

Затем в class у вас есть 2 варианта:

Во-первых:

class SomeClass : SomeProtocol {
    class func someMethod()
}

Второе:

class SomeClass : SomeProtocol {
    static func someMethod()
}

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

Ответ 2

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

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

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

Как и в случае с требованиями типа, вы всегда используете метод типа prefix требования с ключевым словом static, если они определены в протокол. Это верно, даже если требования метода типа с префиксом класса или статического ключевого слова при реализации класса...

Ответ 3

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

class ClassA: MyProtocol{

    static func dummyClassMethod() {

    }
} 

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