我一直在Swift中处理这个问题一段时间,尝试过类型擦除和各种各样的东西,但无济于事;这个问题似乎是常识(至少对我而言)。如何在Swift中模拟抽象类?换句话说,如何使这项工作:
import Foundation
protocol NodeProtocol
{
associatedtype NodeType
func getNode() -> NodeType
}
class Node: NodeProtocol
{
typealias NodeType = Node
var next:Node = Node()
func getNode() -> Node {
return next
}
}
class AbstractGraph<NodeType:NodeProtocol>
{
var root: NodeType?
func getRoot () -> NodeType?{
return root?.getNode()
}
}
注意:这只是我写的一些随机代码,只是为了解决问题的核心。
答案 0 :(得分:0)
我不确定我是否正确地理解了你的问题(你实际上是在问一对夫妻),但这就是我的模仿方式&#39; Swift(4):
中的抽象类protocol Node {
func getNext() -> Node
}
extension Node {
func getNext() -> Node {
fatalError("getNext is not implemented!")
}
}
struct StringNode: Node {
var data: String!
}
let sNode = StringNode(data: "test-node-1")
sNode.getNext()
在协议上使用扩展名,我决定使用fatalError()调用来实现哪些函数 。
现在Node
的每个Node后代必须实现getNext(),否则我们会崩溃。在操场上运行上面的代码,你会发现它会在最后一行崩溃,迫使你实现getNext()。
&#39;修复&#39;将是:
protocol Node {
func getNext() -> Node
}
extension Node {
func getNext() -> Node {
fatalError("getNext is not implemented!")
}
}
struct StringNode: Node {
var data: String!
func getNext() -> Node {
return StringNode(data: "test-node-2")
}
}
let sNode = StringNode(data: "test-node-1")
sNode.getNext()
现在它不会在最后一行崩溃。所有在操场上使用Xcode 9和Swift 4进行测试。
注意:这不是此Node
协议的最佳实现。该协议应列出可操作的方法,该方法应表示Node
,称为NodeOperatable
。应该创建一个名为Node
的类,实现此NodeOperatable
而不实现getNext()
,这将强制后代类实现getNext()
。
答案 1 :(得分:0)
试试这个:
class AbstractGraph<T: NodeProtocol> {
var root: T?
func getRoot () -> T.NodeType? {
return root?.getNode()
}
}
你称之为什么并不重要。在上面我把它命名为T
。在你的作品中,你将其命名为NodeType
,如下所示:
class AbstractGraph<NodeType: NodeProtocol>
但重复使用NodeType
作为类型名称只会让associatedtype NodeType
中的NodeProtocol
名称混淆,人们会期望两者都相同,但事实并非如此。
基本上,您的AbstractGraph
需要符合T
的类型,例如NodeProtocol
。
由于此类型T
符合NodeProtocol
,因此其中会自动包含NodeType
属性。
此外,根据协议要求,getNode()
将返回此NodeType
属性
因此,在getRoot()
,因为您基本上返回getNode()
返回的内容,您需要返回T
类型的NodeType
属性,而不是类型T
本身。