In the case of the following code, it is possible to call both Base.f()
and Sub.f()
because the sub class inherits its parent class's static method.
But I want to use only Base.f()
, and don't want to use Sub.f()
in my code.
Base.f()
and Sub.f()
do the same thing in the following case.
If both Base.f()
and Sub.f()
are used in my code, it just makes my code complex and difficult to find the places where f() are used.
Is it possible to tell swift to generate a compile error if Sub.f()
is used?
Or, is there an alternative way to do it other than to define f() as a global function?
class Base {
static func f() {
print("hello world")
}
}
class Sub: Base {
}
Base.f()
// hello world
Sub.f()
// hello world
CodePudding user response:
The comments of my question contains many good answers:
there is no dedicated swift feature to prevent subclasses from inheriting super class static methods.
move static functions to a new (final) class or struct
use
class
instead ofstatic (=final class)
and override the class method and add@available(*, unavailable)
to it.use Lint tools
I think the easiest way is to create a new (final) class for static methods which do not depend on subclasses, though, that sacrifices code completion feature a little.
I hope someday Swift will introduce @noInherit static func
attribute.
CodePudding user response:
What you're precisely asking is impossible, because the only public/internal members that are not inherited by subclasses are initializers—and only when a subclass defines its own designated initializer, without implementations of all of its superclass's initializers.
So, to abuse that capability, you can use failable initializers when you don't need a return value…
class Base {
init() { }
@discardableResult init?(printingHelloWorld: Void) {
print("hello world")
return nil
}
}
class Sub: Base {
init(_: Any) {
super.init()
}
}
Base(printingHelloWorld: ())
…or throwing initializers, when you do.
class Base {
init() { }
struct Error: Swift.Error {
let payload: String
}
init(returningAPayload: @autoclosure () -> Never) throws {
throw Error(payload: "