泛型类等于

xx

我创建了一个旨在用作“抽象类”的类(仅可进行子类化,而不能直接实例化)。由于Swift不支持此功能,因此必须在抽象方法的主体中使用例如fatalError进行仿真。

我的抽象类必须是平等的。所以我想,我在equals方法中使用fatalError:

class MySuperClass:Equatable {
}

func ==(lhs: MySuperClass, rhs: MySuperClass) -> Bool {
    fatalError("Must override")
}

class MySubClass:MySuperClass {
    let id:Int

    init(_ id:Int) {
        self.id = id
    }
}

func ==(lhs: MySubClass, rhs: MySubClass) -> Bool {
    return lhs.id == rhs.id
}


let a = MySubClass(1)
let b = MySubClass(2)
let c = MySubClass(2)

a == b
b == c

这行得通。我的子类有一个类型参数,但我有一个小问题。现在该示例如下所示:

class MySuperClass:Equatable {
}

func ==(lhs: MySuperClass, rhs: MySuperClass) -> Bool {
    fatalError("Must override")
}

class MySubClass<T>:MySuperClass {
    let id:Int

    init(_ id:Int) {
        self.id = id
    }
}

func ==<T>(lhs: MySubClass<T>, rhs: MySubClass<T>) -> Bool {
    return lhs.id == rhs.id
}


let a = MySubClass<Any>(1)
let b = MySubClass<Any>(2)
let c = MySubClass<Any>(2)

a == b
b == c

现在它崩溃了,因为它没有“看到”重载的等于,并且只在超类中执行了等于。

我知道Swift对于使用泛型类型的覆盖存在一些问题。我以为这只限于与obj-c交互。这至少看起来像一种语言缺陷或错误,如果B是A的子类,为什么为什么泛型B的等价项不会覆盖A类的等价项?

礼貌的麋鹿

正如Airspeed所暗示的那样,问题在于运算符的实现不是类/结构实现的一部分=>因此,继承在那里不起作用。

你可以做的就是保持逻辑内部类实现的,让运营商使用它。例如,以下将满足您的需求:

class MySuperClass: Equatable {

    func isEqualTo(anotherSuperClass: MySuperClass) -> Bool {
        fatalError("Must override")
    }

}

func == (lhs: MySuperClass, rhs: MySuperClass) -> Bool {
    return lhs.isEqualTo(rhs)
}

class MySubClass<T>:MySuperClass {

    let id: Int

    init(_ id: Int) {
        self.id = id
    }

    override func isEqualTo(anotherSuperClass: MySuperClass) -> Bool {
        if let anotherSubClass = anotherSuperClass as? MySubClass<T> {
            return self.id == anotherSubClass.id
        }

        return super.isEqualTo(anotherSuperClass) // Updated after AirSpeed remark
    }

}

let a = MySubClass<Any>(1)
let b = MySubClass<Any>(2)
let c = MySubClass<Any>(2)

a == b
b == c

...如您所见,==operator仅定义一次,并且使用MySuperClass的方法来确定其两个参数是否相等。然后.isEqualTo()处理其余的内容,包括在MySubClass层次上使用继承机制

UPD

上述方法的好处在于,以下方法仍将起作用:

let a2: MySuperClass = a
let b2: MySuperClass = b
let c2: MySuperClass = c

a2 == b2
b2 == c2

...即,无论在编译时使用哪种变量类型,其行为都将由实际的实例类型决定。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档