I watched "Protocol-Oriented Programming in Swift" and read the related docs, but I still think there is a conflict in the following sample code (try it in a Playground).
protocol X {
    // The important part is "static" keyword
    static var x: String { get }
}
extension X {
    // Here "static" again
    static var x: String {
        get {
            return "xxx"
        }
    }
}
// Now I'm going to use the protocol in a class, BUT
// in classes "static" is like "final class",
// i.e. CAN'T BE OVERRIDDEN, right?
// But I'd prefer to have the ability to override that property,
// so I'll try to use "class" keyword.
// Will it break the program? (spoiler: no!)
class Y: X {
    // Here we are allowed to use "class" keyword (but why?).
    class var x: String {
        get {
            return "yyy"
        }
    }
}
class Z: Y {
    override class var x: String {
        get {
            return "zzz"
        }
    }
}
class Test<T: X> {
    func test() -> String {
        return T.x
    }
}
// And finally the property is successfully overridden (but why?).
print(Test<Z>().test()) // "zzz\n"
Does this actually mean that static keyword from protocol (and possible default implementation) can be legitimately  replaced with class keyword when the protocol used in classes? Do you know any references confirming that?
An extension can't be overridden because the way Swift implement extension is using static dispatch which means its resolved at compile time. Ok, actually above code can be compiled using some tricks if it is your goal to make the code compile.
Yes a major one, unfortunately, Swift does not allow us to store property in extension, the compiler bark on us. “Extensions must not contain stored properties”.
You create static variable by appending static keyword in front of your variable declaration. We will be using playground to explore more. When we define any variable as let, it means it's values cannot be modified, On the other hand if we define any variable as var it means it's values can be modified.
One protocol can inherit from another in a process known as protocol inheritance. Unlike with classes, you can inherit from multiple protocols at the same time before you add your own customizations on top. Now we can make new types conform to that single protocol rather than each of the three individual ones.
From Language Reference / Declarations we know the following.
Function Declaration
...
Special Kinds of Methods
...
Methods associated with a type rather than an instance of a type must be marked with the
staticdeclaration modifier for enumerations and structures or theclassdeclaration modifier for classes.
I.e. the static keyword is (mainly) for enumerations and structures and the class keyword is for classes.
There is also such a note:
Type Variable Properties
...
NOTE
In a class declaration, the keyword
statichas the same effect as marking the declaration with both theclassandfinaldeclaration modifiers.
I.e. the static keyword actually can be used in class declaration and will mean final class.
Protocol Method Declaration
...
To declare a class or static method requirement in a protocol declaration, mark the method declaration with the
staticdeclaration modifier. Classes that implement this method declare the method with theclassmodifier. Structures that implement it must declare the method with thestaticdeclaration modifier instead. If you’re implementing the method in an extension, use theclassmodifier if you’re extending a class and thestaticmodifier if you’re extending a structure.
Here the docs state that we should replace the static keyword from protocol declaration with the class keyword when implementing the protocol in a class or a class extension (and this is the exact answer to the original question).
There are two cases in which protocol adoption will be restricted to classes only. The first (and the least explicit) is when a protocol includes optional members:
Protocol Declaration
...
By default, types that conform to a protocol must implement all properties, methods, and subscripts declared in the protocol. That said, you can mark these protocol member declarations with the
optionaldeclaration modifier to specify that their implementation by a conforming type is optional. Theoptionalmodifier can be applied only to protocols that are marked with theobjcattribute. As a result, only class types can adopt and conform to a protocol that contains optional member requirements. ...
And the second (explicit; the next paragraph):
To restrict the adoption of a protocol to class types only, mark the protocol with the
classrequirement by writing theclasskeyword as the first item in the inherited protocols list after the colon. ...
But neither of them changes the rules considering the static and the class keywords applicability.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With