我试图创建一个其子类可以具有更专门的成员的类(字典),然后出现以下错误:
error: property 'dict' with type '[Int : B]' cannot override a property with type '[Int : A]'
这是我的代码:
class A {}
class B: A {} // subclass of A
let dict = [Int:B]()
print(dict is [Int:A]) // true
class MyDict {
var dict = [Int:A]()
}
class MyDict2: MyDict {
/*
⛔ error:
property 'dict' with type '[Int : B]' cannot override a property with type '[Int : A]'
*/
override var dict = [Int:B]()
}
我的问题是,由于[Int:B]
的实例是[Int:A]
,为什么我们不能用[Int:A]
覆盖[Int:B]
类型的字典?
实际上,我试图为加权图和未加权图设计类型。以下是我的实现:
// unweighted edge
public class Edge<Vertex:Hashable> {
public let start: Vertex
public let end : Vertex
init(from start: Vertex, to end: Vertex) {
self.start = start
self.end = end
}
}
// weighted edge
public class WeightedEdge<Vertex:Hashable, Weight:Comparable> : Edge<Vertex> {
public let weight: Weight
init(from start:Vertex, to end:Vertex, weight:Weight) {
self.weight = weight
super.init(from:start, to:end)
}
}
// unweighted graph (definition)
public class Graph<Vertex:Hashable> {
// edges dictionary
var edgesOf = [Vertex: [Edge<Vertex>]]()
// g.addEdge(from:to:bidirectional:)
public func addEdge(
from start: Vertex,
to end:Vertex,
bidirectional:Bool = false
) {
edgesOf[start, default:[]].append(Edge(from: start, to:end))
if bidirectional {
edgesOf[end, default:[]].append(Edge(from: end, to:start))
}
}
}
// weighted graph (definition)
public class WeightedGraph<Vertex:Hashable, Weight:Comparable> : Graph<Vertex> {
public override func addEdge(from start:Vertex, to end:Vertex, bidirectional:Bool = false) {
fatalError("Can't add an unweighted edge to a weighted graph❗")
}
// g.addEdge(from:to:weight:bidirectional:)
public func addEdge(
from start: Vertex,
to end: Vertex,
weight : Weight,
bidirectional: Bool = false
) {
edgesOf[start, default:[]].append(
WeightedEdge(from: start, to:end, weight:weight)
)
if bidirectional {
edgesOf[end, default:[]].append(
WeightedEdge(from: end, to:start, weight:weight)
)
}
}
}
let g = WeightedGraph<Int,Int>()
g.addEdge(from: 3, to: 4, weight:7, bidirectional: true)
g.addEdge(from: 1, to: 3) // fatalError
它对我来说很好,但是我为它的丑陋部分感到困扰:
public override func addEdge(from start:Vertex, to end:Vertex, bidirectional:Bool = false) {
fatalError("Can't add an unweighted edge to a weighted graph❗")
}
如何防止加权图向自身添加未加权的边?
答案 0 :(得分:0)
当您继承一个类时,您将在其中包含超类,因此您将获得同一属性的冲突定义,MyDict2
的编译版本将有所简化
class MyDict2 {
var dict = [Int:A]()
var dict = [Int:B]()
}
,如您所见,这将不起作用。或者,将替换dict
属性,但是您遇到的问题是,任何接受类型为MyDict
的参数的函数也可以采用MyDict2
的实例,但是如果该函数访问了{{ 1}}属性,它将发现类型为dict
的值,而该函数将不知道什么是什么,因为它被定义为采用B
,因此只知道MyDict
我不认为继承是解决问题的替代方法,替代方法是拥有两个单独的类,这些类符合访问底层存储(dict)的相同协议或使用泛型实现
A