如何在Swift中创建抽象类
协议,协议扩展,协议一致性
Swift中没有抽象类(就像Objective-C一样)。 最好的选择是使用协议,就像Java接口一样。 然后,借助Swift 2.0,您可以使用协议扩展添加方法实现和计算的属性实现。 唯一的限制是您不能提供成员变量或常量 , 也没有动态分配 。
怎么运行的
如果您熟悉Objective-C,协议并不是什么新鲜事物。 为了说明此解决方案,以下示例定义了一个具有单实例方法要求的协议:
协议RandomNumberGenerator {func random()-> Double}
该协议RandomNumberGenerator
,要求任何符合条件的类型都具有一个称为random
的实例方法,该方法在每次调用时都会返回Double
值。
这是采用并符合RandomNumberGenerator
协议的类的实现。 此类实现称为线性同余生成器的伪随机数生成器算法:
可以扩展协议以将方法,初始化程序,下标和计算属性实现提供给符合类型。 这使您可以定义协议本身的行为,而不是每种类型的单独一致性或全局函数。
例如,可以扩展randomBool()
协议以提供randomBool()
方法,该方法使用所需的random()
方法的结果返回随机的Bool
值:
扩展 RandomNumberGenerator {func randomBool ()-> Bool {return random()> 0.5}}
通过在协议上创建扩展,所有符合类型的类型都会自动获得此方法的实现,而无需进行任何其他修改。
协议扩展可以将实现添加到符合标准的类型,但不能使协议扩展或从另一个协议继承。 协议继承始终在协议声明本身中指定。
礼宾员工{
var AnnualSalary:Int {get}
}扩展员工{
var biweeklySalary:Int {
返回self.annualSalary / 26
} func logSalary(){
print(“每年$ \(self.annualSalary)或每两周$ \(self.biweeklySalary)”)
}
} struct SoftwareEngineer:员工{
var AnnualSalary:Int func logSalary(){
打印(“覆盖”)
}
} let sarah = SoftwareEngineer(年薪:100000)
sarah.logSalary()//打印:已覆盖
(sarah作为Employee).logSalary()//打印:每年$ 100000或每两周$ 3846
注意,这甚至为结构提供了“抽象类”之类的功能,但是类也可以实现相同的协议。
还要注意,每个实现Employee协议的类或结构都必须再次声明AnnualSalary属性。
最重要的是,请注意没有动态调度 。 在存储为SoftwareEngineer
的实例上调用logSalary
,它将调用该方法的重写版本。 在将logSalary
为Employee
之后在实例上调用logSalary
,它将调用原始实现(即使实例实际上是一名Software Engineer
它也不会动态调度到覆盖的版本。
您可以使用类型转换中描述的is
和as
运算符来检查协议一致性,并转换为特定协议。 检查和转换为协议遵循与检查和转换为类型完全相同的语法:
- 如果实例符合协议,则
is
运算符返回true
否则返回false
。 -
as?
向下运算符的版本返回协议类型的可选值,如果实例不符合该协议,则该值为nil
。 -
as!
向下转换操作符的版本会强制向下转换为协议类型,如果向下转换失败,则会触发运行时错误。
希望你喜欢这个解释。 如有其他疑问,请访问-iOS专家系列或访谈系列
参考文献:
- https://docs.swift.org/swift-book/