You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中单例模式的继承:如何定义泛型静态单例默认值

我懂你想要的那种简洁方案——不用让子类额外实现协议,只靠继承基类就能自动拿到专属的泛型静态单例对吧?刚好有个很适配的实现思路,我用Swift给你举个具体例子(核心逻辑在其他支持泛型和静态属性的语言里也通用):

核心实现方案
// 仅用于继承的泛型基类,禁止直接实例化
class BaseApi<T: BaseApi<T>> {
    // 泛型静态单例默认值,每个子类会拥有自己独立的实例
    static let defaultValue: T = T()
    
    // 私有初始化方法,确保基类只能被继承,不能直接创建实例
    private init() {}
}

// 子类FooApi,无需额外实现任何协议,自动获得单例
class FooApi: BaseApi<FooApi> {
    // 自定义业务方法
    func fetchFooData() {
        print("正在获取Foo相关数据...")
    }
}

// 子类BarApi,同样自动拥有专属单例
class BarApi: BaseApi<BarApi> {
    func fetchBarData() {
        print("正在获取Bar相关数据...")
    }
}

方案优势

  • 无需协议实现:子类只需要继承基类时把自身作为泛型参数传入,就能自动获得defaultValue单例,完全省去了协议适配的冗余代码
  • 类型安全:每个子类的单例都是对应子类的类型,调用方法时不需要额外类型转换
  • 基类保护:私有初始化方法确保基类永远不会被直接实例化,只能作为父类被继承

其他语言适配(以Kotlin为例)

如果你用的是Kotlin,思路类似,借助reified泛型和伴生对象实现:

// 抽象基类,仅用于继承
abstract class BaseApi<T : BaseApi<T>> {
    companion object {
        // 懒加载的泛型单例,确保每个子类只初始化一次
        inline fun <reified T : BaseApi<T>> defaultValue(): T {
            return lazyHolder.getOrPut(T::class) {
                T::class.java.getDeclaredConstructor().newInstance()
            } as T
        }
        
        private val lazyHolder = mutableMapOf<Class<*>, Any>()
    }
    
    // 私有构造,禁止直接实例化基类
    private constructor()
}

class FooApi : BaseApi<FooApi>() {
    fun fetchFooData() {
        println("正在获取Foo相关数据...")
    }
}

// 使用方式
FooApi.defaultValue<FooApi>().fetchFooData()

这个方案完全贴合你“基类仅被继承,定义泛型静态单例默认值”的需求,比协议实现更简洁直观,子类的接入成本极低。

内容的提问来源于stack exchange,提问作者A T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:08:30