超类属性未在Derived类中初始化

我有以下的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实例中初始化,我得到和IndexOutOfBoundsException。 为什么会发生?

TL; DRDGraph构造器参数中删除override val

您的代码与以下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