协议方法是不是意味着在 Swift 中被覆盖?

Posted

技术标签:

【中文标题】协议方法是不是意味着在 Swift 中被覆盖?【英文标题】:Are protocol methods meant to be overriden in Swift?协议方法是否意味着在 Swift 中被覆盖? 【发布时间】:2018-05-20 12:44:40 【问题描述】:

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

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

要开始以抽象的方式思考,我想知道协议方法是否意味着在 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 


【问题讨论】:

【参考方案1】:

你说得对,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

【讨论】:

我遵循了你关于静态常量的最后一个示例,但是我对“作为约束”这个词感到有些困惑。不过我真的很想理解它,所以我必须继续阅读,除非你能澄清你所说的“作为约束”是什么意思? @CosmicArrows 我现在添加了一个示例

以上是关于协议方法是不是意味着在 Swift 中被覆盖?的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 必须被子类覆盖的类方法

如何覆盖子类的 swift 协议函数(例如 UIView 中的 UILabel)

在 Swift 中,如何测试一个对象是不是实现了一个可选的协议方法,该方法在签名上有所不同,而无需实际调用该方法?

是否有可能有一个强制静态方法而不是类方法的 Swift 协议,反之亦然?

调用 Swift 协议扩展方法而不是子类中实现的方法

java如何调用父类的父类中被覆盖的方法