How to properly implement the Equatable protocol in a class hierarchy?
Following the other answers I came up with this:
class Base : Equatable {
var x : Int
static func == (lhs: Base, rhs: Base) -> Bool {
return lhs.x == rhs.x
}
}
class Subclass : Base {
var y : String
static func == (lhs: Subclass, rhs: Subclass) -> Bool {
return lhs.y == rhs.y && (lhs as Base) == (rhs as Base)
}
}
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
.
For the base class this became:
func == (lhs: Base, rhs: Base) -> Bool {
return lhs.x == rhs.x
}
class Base : Equatable {
var x : Int
}
And for the subclass:
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
}
That first if
statement results in a call to the ==
operator in the base class.
The final solution:
Base.swift:
func == (lhs: Base, rhs: Base) -> Bool {
return lhs.x == rhs.x
}
class Base : Equatable {
var x : Int
}
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
}