首页 > 解决方案 > 协议方法是否意味着在 Swift 中被覆盖?

问题描述

我已经开始阅读一本关于 Swift 中面向协议编程的教科书。当我在操场上写代码时,我注意到书中的一种方法使用了关键字“静态”。据我了解,静态方法意味着该方法将由类型本身调用,而不是由该类型的特定实例调用。我的理解是,静态方法不能被覆盖。

由于协议在声明时只是方法签名,我认为看到使用关键字“静态”有点奇怪,因为无论如何我们都必须实现函数的存根。

要开始以抽象的方式思考,我想知道协议方法是否意味着在 Swift 中被覆盖,或者关键字“静态”的使用是否只是使其只有类型本身可以调用方法而不是其实例调用方法?

protocol YourProtocol {

    //property requirements that types that conform to this protocl MUST implement
    var gettableProperty: String { get }
    var gettableSettableProperty: Int { get set }

    //method requirements that types that conform to this protocol MUST implement
    func someMethod(parameter1: Double) -> String


    static func staticMethod() -> Float 

}

标签: swiftprotocolsstatic-methods

解决方案


你是对的,static方法不能被覆盖,因为它们总是绑定到一个特定的类型,但是,static协议中的方法声明可以使用class方法来实现。并且class方法可以被覆盖:

protocol YourProtocol {
    static func staticMethod() -> Float
}

class A: YourProtocol {
    class func staticMethod() -> Float {
        return 1.0
    }
}

class B: A {
    override class func staticMethod() -> Float {
        return 2.0
    }
}

此外,被覆盖的能力不是核心点。我认为这个概念可以在static常量或static变量 getter 上更好地理解,以静态库为例:

public protocol FloatingPoint: ... {
   public static var pi: Self { get }
}

该协议由所有浮点类型实现,例如DoubleFloat它们甚至不是类,因此它们不支持继承和覆盖。在声明使用该协议作为类型约束的泛型方法时,甚至可以在协议中声明它们的静态常量这一事实:

func toDegrees<T: FloatingPoint>(radians: T) -> T {
    // the .pi here is a static var getter
    return radians * 180 / T.pi
}

推荐阅读