ios - 将协议(protocol)添加到父类(super class),这将强制从它继承的其他类实现协议(protocol)

标签 ios swift inheritance swift-protocols

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

假设您的公司有两种不同类型的员工:工资和小时工(很常见)。现在,他们都将从一个名为 Employee 的父类(super class)继承,并且都必须调用一个名为“pay”的函数来支付员工工资。您如何强制这些类来实现该功能?当然,使用协议(protocol),但这需要您记住将其添加到函数声明中。有没有一种方法可以将协议(protocol)添加到父类(super class)“Employee”,然后从该类继承的任何东西都必须遵循属于该父类(super class)的协议(protocol)。还有另一种方法吗?谢谢!

最佳答案

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

如果 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
    }

}

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

  • Employee 类需要生成某种错误的函数的默认实现
  • 子类实现方法失败不会导致编译时错误

您可以为每个子类分别分配一个协议(protocol),例如 Payable,但是由于该协议(protocol)不是基类的一部分,您不能这样说:

 var employees[Employee]

 for e in employees {
     let pay = e.calculatePay()
 }

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

 for e in employees {
     if e is Payable {
         let pay = e.calculatePay()
     }
 }

关于ios - 将协议(protocol)添加到父类(super class),这将强制从它继承的其他类实现协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47243822/

相关文章:

java - 如何监控 iOS/Android 设备中的 https/ssl 流量

ios - 为 WKWebkitView 运行 localhost

objective-c - 将 @objc 添加到 Swift 方法或变量会产生不良影响吗?

python - 继承和修改 __init__() 方法

iphone - 检测 iPhone 上的蓝牙接听/结束通话按钮

iphone - UIButton 背景 VS UIButton imageview.view

java - 在子类中创建父对象时出错

python - 什么是 Python 中的兄弟类?

ios - 收到推送通知后重定向到特定屏幕 - Swift

ios - 如何动态计算桌面高度?