我有以下Kotlin代码:
import java.util.*
import kotlin.collections.HashSet
open class Graph(open val n: Int) {
val graph = List<MutableSet<Int>>(n) {HashSet<Int>()}
open fun addEdge(u: Int, v: Int) {
graph[u].add(v)
graph[v].add(u)
}
val numEdges: Int
get() {
return graph.asSequence()
.map { it.size }
.reduce { x, y -> x + y }
}
fun edgeSet() : HashSet<Pair<Int,Int>> {
val result = HashSet<Pair<Int,Int>>()
for (i in graph.indices) {
for(j in graph[i]) {
if(i<j) result.add(i to j)
else result.add(j to i)
}
}
return result;
}
override fun toString(): String {
return "Graph(n=$n, graph=$graph)"
}
}
class DGraph(override val n: Int) : Graph(n) {
override fun addEdge(u: Int, v: Int) {
graph[u].add(v)
}
}
但是,当我创建DGraph的实例时,请在以下代码中使用它:
val graph = DGraph(5)
println(graph.graph.size)
graph.addEdge(0,1)
我发现在DGraph实例中没有初始化graph属性,我得到了IndexOutOfBoundsException。为什么会这样?
答案 0 :(得分:1)
TL; DR 从override val
构造函数参数中删除DGraph
。
您的代码秘密等同于以下Java伪代码:
class Graph {
private final int n;
private final List<MutableSet<Int>> graph;
Graph(int n) {
this.n = n;
this.graph = someStuffThatCreatesAList(getN());
}
int getN() { return n; }
// ...
}
class DGraph extends Graph {
private final int n;
DGraph(int n) {
super(n);
this.n = n;
}
int getN() { return n; }
// ...
}
所以在Graph
构造函数中,覆盖getN
被调用。但是,子类成员尚未初始化,因此它返回默认值(0
)。
删除override val
后,您可以取消对getN
的覆盖。