你所需要的是一个“抽象类”。抽象类的目的是作为具体类继承的基类,但是不能直接实例化。
如果“Employee”是抽象类,那么试图实例化“Employee”的任何尝试都将被编译器报告为错误。你需要实例化“Employee”的具体子类,例如“SalariedEmployee”或“HourlyEmployee”。
“Employee”类的定义将包括“calculatePay”方法是必需的,如果具体子类没有实现该方法,则会产生编译时错误。
现在,坏消息是,Objective-C和Swift都不支持抽象类。
你可以提供一种类似的类,通过提供一个实现了抛出异常方法的方法,如果没有被子类覆盖,则会产生运行时错误,而不是编译时错误。
例如:
class Employee {
var givenName: String
var surname: String
...
init(givenName: String, surname: String) {
self.givenName = givenName
self.surname = surname
}
func calculatePay() -> Float {
fatalError("Subclasses must override calculatePay")
}
}
class SalariedEmployee: Employee {
var salary: Float
init(givenName: String, surname: String, annualSalary: Float) {
salary = annualSalary
super.init(givenName: givenName, surname: surname)
}
override func calculatePay() -> Float {
return salary/12 // Note: No call to super.calculatePay
}
}
无论是
calculatePay
是作为基类的一部分还是通过扩展分配给基类并添加符合协议,结果都是相同的;
Employee
类将需要一个生成某种错误的函数的默认实现
- 子类未实现该方法不会导致编译时错误
你可以为每个子类单独分配一个协议,例如 Payable
,但是由于该协议不是基类的一部分,因此您无法说出这样的话:
var employees[Employee]
for e in employees {
let pay = e.calculatePay()
}
您需要使用略微复杂的方法:
for e in employees {
if e is Payable {
let pay = e.calculatePay()
}
}