Swift子类是否符合可调用的超类实现?


class Base: Equatable {
static func == (lhs: Base, rhs: Base) -> Bool {
lhs.id == rhs.id
}
let id: String
init(id: String) {
self.id = id
}
}
class SubClass: Base {
public var id2: String?
public init(id1: String, id2: String? = nil) {
self.id2 = id2
super.init(id: id1)
}
static func == (lhs: SubClass, rhs: SubClass) -> Bool {
lhs.id2 == rhs.id2 && lhs.id == rhs.id
}
}
print(a != b) // result: false
// Calls `Base` class's static func ==
print(a == b) // result: false
// Calls `SubClass` class's static func ==

我有一个简单的超类和子类,子类继承Base并实现static func ==

调用a != b时,调用Base类的==实现,而不是SubClass==实现,为什么?但是当调用a == b时,它实际上调用的是SubClass==实现,为什么?

我期望!===调用SubClass==实现

这个问题早在Swift语言改进后就存在了(https://github.com/apple/swift-evolution/blob/master/proposals/0091-improving-operators-in-protocols.md)

作者也提到了这个问题。你可以检查一下。https://github.com/apple/swift-evolution/blob/master/proposals/0091-improving-operators-in-protocols.md class-types-and-inheritance

我找到的一个解决方案是定义一个isEqual函数。

class Superclass: Equatable {
var foo: Int
init(foo: Int) {
self.foo = foo
}
func isEqual(to instance: Superclass) -> Bool {
return self.foo == instance.foo
}
static func ==(lhs: Superclass, rhs: Superclass) -> Bool {
return type(of: lhs) == type(of: rhs) && lhs.isEqual(to: rhs)
}
}
class Subclass: Superclass {
var bar: String
init(foo: Int, bar: String) {
self.bar = bar
super.init(foo: foo)
}
override func isEqual(to instance: Superclass) -> Bool {
guard let instance = instance as? Subclass else {
return false
}
return self.foo == instance.foo && self.bar == instance.bar
}
}
let a = Subclass(foo: 1, bar: "a")
let b = Subclass(foo: 1, bar: "b")
print(a == b) // False
print(a != b) // True

参考:

  • https://forums.swift.org/t/method-dispatching-issue-with-subclasses-implementing-equatable-protocol/4925
  • https://forums.swift.org/t/implement-equatable-protocol-in-a-class-hierarchy/13844

最新更新