如何在Swift中重写泛型类中的泛型方法?

9
我正在学习Swift编程语言。 我想要在泛型类中重载泛型函数。 当我使用"override"关键字时,编译错误会发生。
class GenericParent<U> {
    func genericFunc<T>(param: T) { print("parent") }
}

class AbsoluteChild: GenericParent<Int> {
    override func genericFunc<T>(param: T) { print("child") }
    // ! Method does not override any method from its superclass (compile error)
}

我可以省略 override 关键字。 但是当我将对象类型声明为“Parent”时,父类的方法被调用(而不是子类的方法)。它并非真正的“覆盖”。

class GenericParent<U> {
    func genericFunc<T>(param: T) { print("parent") }
}

class AbsoluteChild: GenericParent<Int> {
    func genericFunc<T>(param: T) { print("child") }
}

var object: GenericParent<Int>
object = AbsoluteChild()
object.genericFunc(1) // print "parent" not "child"

// I can call child's method by casting, but in my developing app, I can't know the type to cast.
(object as! AbsoluteChild).genericFunc(1) // print "child"

在这个例子中,我希望通过object.genericFunc(1)来获得“child”作为结果。(换句话说,我想要“覆盖”这个方法。)
如何实现这一点呢?有没有什么变通方法可以做到这一点?
我知道我可以通过转型来调用子类的方法。但是在我正在开发的实际应用程序中,我不知道要转型的类型,因为我想让它具有多态性。
我也阅读了Overriding generic function error in swift的文章,但是我无法解决这个问题。
谢谢!

object是一个GenericParent<Int>只是告诉编译器有哪些方法和属性可用。它并不会将类从AbsoluteChild更改为GenericParent<Int>GenericParent<Int>使得genericFunc方法可用,但object仍然是一个AbsoluteChild;这意味着当你调用genericFunc时,它将调用子类的实现。你不能将对象强制转换为其父类以获取父类的实现。 - keithbhunter
谢谢!但是当我在playground中执行第二个示例时,object.genericFunc(1)打印出“parent”。这意味着调用了父类的实现。我该如何理解这个问题? - Yoshikuni Kato
哦,我也看到了。那似乎是个漏洞。你可以将其提交为漏洞报告到bugreport.apple.comSwift GitHub页面 - keithbhunter
这个问题可能与以下问题相同。https://bugs.swift.org/browse/SR-103 - Yoshikuni Kato
由于T是泛型,编译器不知道它要覆盖哪种类型的函数。我期望有一种“关联类型”,但不幸的是我没有电脑来测试我的想法。 - jboi
1个回答

1
这个问题在Swift 5中已解决:
class GenericParent<U> {
    func genericFunc<T>(param: T) { print("parent") }
}

class AbsoluteChild: GenericParent<Int> {
    func genericFunc<T>(param: T) { print("child") }
}

var object: GenericParent<Int>
object = AbsoluteChild()
object.genericFunc(1) // print "parent" not "child"

// I can call child's method by casting, but in my developing app, I can't know the type to cast.
(object as! AbsoluteChild).genericFunc(1) // print "child"

现在会触发一个错误:

覆盖声明需要使用 'override' 关键字

使用以下内容进行修正:

class AbsoluteChild: GenericParent<Int> {
    override func genericFunc<T>(_ param: T) { print("child") }
}

代码编译并且两次都打印出了“child”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接