将协议添加到超类,这将强制从它继承的其他类实现协议

hum*_*der 4 inheritance ios swift swift-protocols

所以我是 iOS 开发的新手,并且在我的实习期间一直致力于对具有相对较大的 Objective-c 代码库的应用程序进行细微的更改。我一直在从 Treehouse 快速学习(哇,爱他们!),我刚刚了解了协议。目前,它们应该在某些情况下使用,并且教师使用了这个例子。

假设您有一家拥有两种不同类型员工的公司:Salary 和 Hourly(很常见)。现在,他们都将从一个名为 Employee 的超类继承,并且都必须调用一个名为“pay”的函数来支付雇员的工资。您如何强制这些类来实现该功能?当然,使用协议,但这需要您记住将其添加到函数声明中。有没有办法将协议添加到超类“Employee”,然后从该类继承的任何内容都必须遵循该超类的一部分的协议。有没有另一种方法可以做到这一点?谢谢!

Pau*_*w11 5

您正在寻找的是一个抽象类抽象类的目的是作为具体类继承的基类,但抽象类不能直接实例化。

如果Employee是一个抽象类,那么任何实际实例化实例的尝试Employee都会被编译器报告为错误。您需要实例化 的具体子类Employee,例如SalariedEmployeeHourlyEmployee

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
    }

}
Run Code Online (Sandbox Code Playgroud)

无论calculatePay是基类的一部分,还是通过增加协议一致性的扩展分配给基类,结果都是一样的;

  • Employee班将需要功能的默认实现产生某种错误
  • 子类未能实现该方法不会导致编译时错误

例如,您可以Payable为每个子类单独分配一个协议,但是由于该协议不是基类的一部分,因此您不能这样说:

 var employees[Employee]

 for e in employees {
     let pay = e.calculatePay()
 }
Run Code Online (Sandbox Code Playgroud)

您将不得不使用稍微复杂一点的:

 for e in employees {
     if e is Payable {
         let pay = e.calculatePay()
     }
 }
Run Code Online (Sandbox Code Playgroud)