2017-05-14 5 views
0

私は、次の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) 

IグラフのプロパティがDGraphインスタンスで初期化されていないことを確認して、IndexOutOfBoundsExceptionを取得します。なぜこれが起こるのですか?

+0

'graph'プロパティが初期化されなかった場合、' graph.graph.size'は失敗します。 –

+0

@OliverCharlesworth、はい、私はそれを知っています。しかし、グラフのプロパティが初期化されないのはなぜですか? – enitihas

答えて

1

TL; DRDGraphコンストラクタparamから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になりません。

+0

ありがとうございます。それは今働く。私はエラーを得るためだけにオーバーライドを削除しようとしました。私はDGraphでもnをプロパティとして必要としていたのでvalを削除することは考えていませんでした。今私はそれをすべて理解しています。 – enitihas

関連する問題