如何在类层次结构中正确实现Equatable协议? [英] How to properly implement the Equatable protocol in a class hierarchy?

查看:135
本文介绍了如何在类层次结构中正确实现Equatable协议?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Swift 3的基类及其子类中实现==运算符(来自Equatable).所有这些类仅在Swift中使用,因此我不想涉及NSCopying协议.

I'm trying to implement the == operator (from Equatable) in a base class and its subclasses in Swift 3. All of the classes will only be used in Swift so I do not want to involve NSObject or the NSCopying protocol.

我从基类和子类开始:

class Base {
    var x : Int
}

class Subclass : Base {
    var y : String
}

现在我想将Equatable==运算符添加到Base.似乎很简单.从文档中复制==操作员签名:

Now I wanted to add Equatable and the == operator to Base. Seems simple enough. Copy the == operator signature from the documentation:

class Base : Equatable {
    var x : Int

    static func == (lhs: Base, rhs: Base) -> Bool {
        return lhs.x == rhs.x
    }
}

到目前为止,一切都很好.现在是子类:

So far so good. Now for the subclass:

class Subclass : Base {
    static override func == (lhs: Base, rhs: Base) -> Bool {
        return true
    }
}

但这会导致错误:

运算符功能会覆盖最终"运算符功能

Operator function overrides a 'final' operator function

好.经过一些研究(仍然学习Swift 3),我了解到可以用class替换static,以指示可以重写类型方法.

OK. After some research (still learning Swift 3) I learn that static can be replaced with class to indicate the type method can be overridden.

所以我尝试将Base中的static更改为class:

So I attempt to change static to class in Base:

class Base : Equatable {
    var x : Int

    class func == (lhs: Base, rhs: Base) -> Bool {
        return lhs.x == rhs.x
    }
}

但这会导致新的错误:

在非最终类'Base'中声明的运算符'=='必须为'final'

Operator '==' declared in non-final class 'Base' must be 'final'

U.这要复杂得多.

如何在基类和子类中正确实现Equatable协议和==运算符?

How do I implement the Equatable protocol and the == operator properly in a base class and a subclass?

推荐答案

经过大量研究和反复试验,我终于提出了一个可行的解决方案.第一步是将==运算符从类内部移动到全局范围.这修复了有关staticfinal的错误.

After lots of research and some trial and error I finally came up with a working solution. The first step was moving the == operator from inside the class to the global scope. This fixed the errors about static and final.

对于基类,它变为:

func == (lhs: Base, rhs: Base) -> Bool {
    return lhs.x == rhs.x
}

class Base : Equatable {
    var x : Int
}

对于子类:

func == (lhs: Subclass, rhs: Subclass) -> Bool {
    return true
}

class Subclass : Base {
    var y : String
}

现在剩下的唯一部分是弄清楚如何从子类的==运算符调用基类的==运算符.这导致了我的最终解决方案:

Now the only part left is figuring out how to call the == operator of the base class from the == operator of the subclass. This led me to the final solution:

func == (lhs: Subclass, rhs: Subclass) -> Bool {
    if lhs.y == rhs.y {
        if lhs as Base == rhs as Base {
            return true
        }
    }

    return false
}

第一个if语句导致对基类中的==运算符的调用.

That first if statement results in a call to the == operator in the base class.

最终解决方案:

Base.swift:

Base.swift:

func == (lhs: Base, rhs: Base) -> Bool {
    return lhs.x == rhs.x
}

class Base : Equatable {
    var x : Int
}

Subclass.swift:

Subclass.swift:

func == (lhs: Subclass, rhs: Subclass) -> Bool {
    if lhs.y == rhs.y {
        if lhs as Base == rhs as Base {
            return true
        }
    }

    return false
}

class Subclass : Base {
    var y : String
}

这篇关于如何在类层次结构中正确实现Equatable协议?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆