Swift中如何为不同类声明统一实例名并延迟实例化?
解决Swift延迟类实例化的问题
这个问题其实是典型的多态场景,在Swift里我们有两种常用的解决方式,推荐优先用协议方案,因为它更灵活,不需要类之间有继承关系,我给你详细拆解下:
方案一:使用协议(推荐)
首先我们需要定义一个协议,把A和B共有的属性和方法都统一进去,这样就能用这个协议类型来声明变量,后续可以赋值给任何遵守该协议的类实例:
// 定义协议,统一A、B的公共接口 protocol Calculatable { var x: Int { get set } func calc() }
接下来让A和B都遵守这个协议——因为它们本身已经实现了协议要求的属性和方法,所以只要在类声明里加上协议名就行:
class A: Calculatable { var x: Int = 0 func calc() { x = 10 } } class B: Calculatable { var x: Int = 0 func calc() { x = 33 } }
现在回到你的X类,把AorB变量的类型声明为Calculatable?(用可选型是因为要延迟初始化,后续再赋值):
class X: UIViewController { var value: Int = 0 // 用协议类型声明变量,后续可赋值给A或B的实例 var aOrB: Calculatable? override func viewDidLoad() { super.viewDidLoad() // 这里根据你的业务逻辑决定实例化A还是B let shouldUseA = true // 替换成你的实际判断条件 if shouldUseA { aOrB = A() } else { aOrB = B() } // 之后就可以统一调用方法、访问属性了 aOrB?.calc() if let result = aOrB?.x { print(result) // 满足条件的话会输出10或者33 } } }
方案二:使用父类继承
如果A和B本身可以共享一个父类,也可以用继承的方式实现:
先创建一个父类,把共有的属性和方法定义好(Swift没有严格的抽象类,所以可以用fatalError强制子类重写方法):
class BaseCalculation { var x: Int = 0 func calc() { // 强制子类重写该方法 fatalError("子类必须实现calc方法") } }
然后让A和B继承这个父类,并重写calc方法:
class A: BaseCalculation { override func calc() { x = 10 } } class B: BaseCalculation { override func calc() { x = 33 } }
最后在X类里用父类类型声明变量:
class X: UIViewController { var value: Int = 0 var aOrB: BaseCalculation? override func viewDidLoad() { super.viewDidLoad() let shouldUseA = false // 替换成你的判断条件 if shouldUseA { aOrB = A() } else { aOrB = B() } aOrB?.calc() print(aOrB?.x ?? 0) // 这里会输出33 } }
两种方案对比
- 协议方案:更灵活,A和B不需要有继承关系,只要遵守协议就能被统一使用,是Swift推荐的协议优先编程范式。
- 继承方案:适合A和B有更多共性逻辑的场景,但耦合性比协议高。
内容的提问来源于stack exchange,提问作者Jens
相关产品推荐
相关产品推荐

