I'm trying to understand how method dispatch works in Swift for static methods. I wrote the following example:
class Parent {
static func greet() {
print("Hello from Parent")
}
}
class Child: Parent {
static func greet() {
print("Hello from Child")
}
}
I expected this to work, but Swift does not let me, I get this error: Cannot override static method. It tries to fix it by suggesting: Insert 'override '.
I thought static methods are not part of the VTable and therefore aren't meant to be overridden—so why is Swift expecting an override in some cases?
Why does this compile when I mark the method as private?
This works perfectly fine.
class Parent {
private static func greet() {
print("Hello from Parent")
}
}
class Child: Parent {
static func greet() {
print("Hello from Child")
}
}
Also, does this mean that in both cases the method is tied to the type itself, but making it private disable function overloading through static dispatch? How exactly does that work?
That sounds like a bug with the error message — you should open an issue with this example!
Because Child can’t access the Parent.greet method, it doesn’t know that its own greet method has the same name as a method in the parent class. There is no context where code could see both of the greet methods, so there will never be ambiguity.
If you want to make the method overridable you can declare it as a class func instead of a static func.
static is a shorthand spelling for class final so there’s no method dispatch here. A static method inside a class is essentially the same thing as a top-level global function.
The prohibition on two methods having the same name when one is not an override of another is, in a sense, artificial. There’s no technical reason to disallow it, but it would be confuse users if they expected dynamic dispatch to happen when it doesn’t.
Because now the subclass cannot “see” the superclass method, so it is as if the superclass method had a different name.