Swift: The static property in the CAN protocol extension can be overridden, but why?

I watched “Protocol programming in Swift” and read related documents, but I still think that in the following example there is code conflict (try on the 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", // ie 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 Tx } } // And finally the property is successfully overridden (but why?). print(Test<Z>().test()) // "zzz\n" 

Does this mean that the static from the protocol (and a possible default implementation) can be legally replaced with the class keyword when using the protocol in classes? Do you know any links confirming this?

+5
source share
1 answer

From the Language / Declaration Handbook, we know the following.

Function Declaration

...

Special Method Types

...

Methods associated with the type, and not with the type instance, must be marked with a static declaration modifier for enumerations and structures or a class declaration modifier for classes.

those. The static (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 static has the same effect as declaring a declaration using class and final declaration modifiers.

those. The static can actually be used in a class declaration and will mean final class .

What about protocols?

Protocol Protocol Declaration

...

To declare a class or static method requirement in a protocol declaration, mark the method declaration with the static declaration modifier. Classes that implement this method declare the method using the class modifier. Structures that implement it must declare a method using the static declaration modifier. If you apply the method in an extension, use the class modifier if you extend the class and the static modifier if you extend the structure.

The docs document states that we must replace the static from the protocol declaration with the class keyword when implementing the protocol in a class or class extension (and this is the exact answer to the original question).

Bonus

There are two cases where protocol adoption will be limited to classes only. The first (and least pronounced) is when the protocol includes optional participants:

Protocol declaration

...

By default, protocol conformance types must implement all the properties, methods, and indexes declared in the protocol. However, you can mark these declarations of protocol participants with the optional declaration modifier to indicate that their implementation of the appropriate type is optional. The optional modifier can only be applied to protocols marked with the objc attribute. As a result, only class types can accept and conform to a protocol that contains optional member requirements ....

And the second (explicit; next paragraph):

To limit protocol acceptance to classes only, mark the protocol with the class requirement by writing the class keyword as the first item in the list of inherited protocols after the colon ....

But not one of them changes the rules taking into account the applicability of the static and class keywords.

+5
source

Source: https://habr.com/ru/post/1235793/


All Articles