Skip to content

Instantly share code, notes, and snippets.

@untalfranfernandez
Last active July 26, 2020 18:22
Show Gist options
  • Save untalfranfernandez/a5097f1b24379e127674eb1df8c97d96 to your computer and use it in GitHub Desktop.
Save untalfranfernandez/a5097f1b24379e127674eb1df8c97d96 to your computer and use it in GitHub Desktop.
Swift: Subclases and Equatable protocol
class Superclass : Equatable {
let foo: Int
init(foo: Int) { self.foo = foo }
func equal(to: Superclass) -> Bool {
return foo == to.foo
}
}
func == (lhs: Superclass, rhs: Superclass) -> Bool {
return lhs.equal(to: rhs)
}
class Subclass: Superclass {
let bar: Int
init(foo: Int, bar: Int) {
self.bar = bar
super.init(foo: foo)
}
override func equal(to: Superclass) -> Bool {
if let toSub = to as? Subclass {
return bar == toSub.bar && super.equal(to: to)
}
return false
}
}
func == (lhs: Subclass, rhs: Subclass) -> Bool {
return lhs.equal(to: rhs)
}
class SubclassWithDifferentOperator: Subclass {}
func != (lhs: SubclassWithDifferentOperator, rhs: SubclassWithDifferentOperator) -> Bool {
return !lhs.equal(to: rhs)
}
let a = Subclass(foo: 1, bar: 1)
let b = Subclass(foo: 1, bar: 2)
(a == b) != (a != b)
let x = SubclassWithDifferentOperator(foo: 1, bar: 1)
let y = SubclassWithDifferentOperator(foo: 1, bar: 2)
(x == y) != (x != y)
@iComputerfreak
Copy link

iComputerfreak commented Jul 26, 2020

The problem with this approach is, that in the following example

let c = Superclass(foo: 0)
let d = Subclass(foo: 0, bar: 1)
c == d // returns true
d == c // returns false

c == d returns true, which might not be what you want. But more importantly, d == c returns false, which violates the symmetry of the equals operation.

This is, because the first element in the equals relation defines the equal implementation, that is being used.

The only solution for this, I found, is this post in the Swift Forums.
The problem with this solution would be, that we have to check the superclass properties against each other in the subclass implementation. (Subclass has to check the foo property in it's equal function)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment