在以下代碼的情況下,可以呼叫兩者Base.f(),Sub.f()因為子類繼承了其父類的靜態方法。
但我只想使用Base.f(),不想Sub.f()在我的代碼中使用。
Base.f()并Sub.f()在以下情況下做同樣的事情。如果在我的代碼中同時使用Base.f()和Sub.f(),只會使我的代碼變得復雜且難以找到使用 f() 的地方。
如果Sub.f()使用,是否可以告訴 swift 生成編譯錯誤?
或者,除了將 f() 定義為全域函式之外,還有其他方法可以做到嗎?
class Base {
static func f() {
print("hello world")
}
}
class Sub: Base {
}
Base.f()
// hello world
Sub.f()
// hello world
編輯
比列印“hello world”更有意義的例子。
在以下情況下,我不想呼叫它,Sub1.findSubclassByType("sub2")因為Sub1找到子類聽起來很有趣。所以,我想總是用Base.findSubclassByType("sub2").
也許,定義findSubclassByType(type)inBase是一個錯誤的類設計?(雖然,findSubclassByType(type)當我輸入Xcode時,它的建議很方便Base.。)
我該怎么辦?
class Base {
static func findSubclassByType(_ type: String) -> Base {
// find and return a subclass
if type == "sub1" {
return Sub1()
} else if type == "sub2" {
return Sub2()
} else {
fatalError("no sub class")
}
}
}
class Sub1: Base {
}
class Sub2: Base {
}
uj5u.com熱心網友回復:
我的問題的評論包含許多很好的答案:
沒有專門的 swift 功能來防止子類繼承超類靜態方法。
將靜態函式移動到新的(最終)類或結構
使用
class代替static (=final class)并覆寫類方法并添加@available(*, unavailable)到它。使用 Lint 工具
我認為最簡單的方法是為不依賴于子類的靜態方法創建一個新的(最終)類,但這會稍微犧牲代碼完成功能。
我希望有一天 Swift 會引入@noInherit static func屬性。
uj5u.com熱心網友回復:
你確切地問的是不可能的,因為唯一不被子類繼承的公共/內部成員是初始化器——并且只有當子類定義了它自己的指定初始化器時,才沒有實作其所有超類的初始化器。
因此,為了濫用該功能,您可以在不需要回傳值時使用可失敗的初始值設定項……
class Base {
init() { }
@discardableResult init?(printingHelloWorld: Void) {
print("hello world")
return nil
}
}
class Sub: Base {
init(_: Any) {
super.init()
}
}
Base(printingHelloWorld: ())
……或者在你這樣做的時候拋出初始化器。
class Base {
init() { }
struct Error: Swift.Error {
let payload: String
}
init(returningAPayload: @autoclosure () -> Never) throws {
throw Error(payload: "??")
}
}
class Sub: Base {
init(_: Any) {
super.init()
}
}
extension Never {
init() { fatalError() }
}
do {
try Base(returningAPayload: .init())
} catch {
(error as! Base.Error).payload
}
我建議不要這樣做,一般不要進行子類化。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/368990.html
標籤:迅速
