2013-05-15 100 views
2

我是Scala的新手。我如何在類中實現方法?在Scala類中實現可變方法

我已經定義了一個特徵,看起來是這樣的:

trait Node extends Component{ 
    val label:Int 
    val inputEdges:List[Edge] = List[Edge]() 
    val outputEdges:List[Edge] = List[Edge]() 

    def addInputEdge(edge:Edge) = { 
    inputEdges :+ edge 
    this 
    } 

    def addOutputEdge(edge:Edge) = { 
    outputEdges :+ edge 
    this 
    } 
} 

case class SomeNode(label:Int) extends Node 

我需要幫助瞭解如何實現這兩種方法。

每個擴展Node的類都必須在構造函數中提供一個標籤,但應該繼承兩個方法和兩個列表。此外,這些方法應該返回節點的一個新對象,並將邊緣添加到其中一個列表中。現在,如果我調用其中一個方法,我會得到同一個對象,並且沒有邊添加到列表中的一個。這是有道理的,但我不知道如何添加一個邊緣,當兩個列表是不可變的。

我真的不想在構造函數中傳遞列表,然後我將得到具有許多參數的構造函數。

回答

0

我知道你問過一個解決方案,其中列表沒有出現在構造函數中,但是如果你使用默認參數,它希望是可以接受的。 (你爲什麼要避免「發福」的構造函數,默認參數或伴侶對象應用方法可以幫助我在這裏感興趣。)
(順便說一句:在性狀的使用def抽象事物和Seq代替List

這裏是我的方法:

trait Self[S] { self: S => 
    type SELF = S 
} 

trait Component 
trait Edge 

trait Node extends Component { 
    type SELF 
    protected def constructor: (Int, Seq[Edge], Seq[Edge]) => SELF 
    def label: Int 
    def inputEdges: Seq[Edge] 
    def outputEdges: Seq[Edge] 
    private def clone(inputEdges: Seq[Edge] = this.inputEdges, outputEdges: Seq[Edge] = this.outputEdges) = constructor(label, inputEdges, outputEdges) 
    final def addInputEdge(edge: Edge) = clone(inputEdges = inputEdges :+ edge) 
    final def addOutputEdge(edge: Edge) = clone(outputEdges = outputEdges :+ edge) 
} 

case class SomeNode(label: Int, inputEdges: Seq[Edge] = Seq(), outputEdges: Seq[Edge] = Seq()) extends Node with Self[SomeNode] { 
    def constructor = SomeNode 
} 

val node1 = SomeNode(1) 
val node2: SomeNode = node1.addInputEdge(new Edge {}) 
+0

感謝,然而,這似乎比有一個大的構造函數(atlest我)更加混亂。我不喜歡一個大的構造函數,因爲他們很難理解我認爲什麼是類。我只是尋找一種簡單而優雅的解決方案,在OOP語言中這種方法是可變的。 –

0

有幾種方法來實現你在問什麼。首先,您可以簡單地將inputEdges和outputEdges定義爲var s而不是val s。這樣,您可以將您在addInputEdge和addOutputEdge方法中創建的列表重新分配到相應的字段。

trait Node extends Component { 
    val label:Int 
    var inputEdges:List[Edge] = List[Edge]() 
    var outputEdges:List[Edge] = List[Edge]() 

    def addInputEdge(edge:Edge) = { 
    inputEdges = inputEdges :+ edge 
    this 
    } 

    def addOutputEdge(edge:Edge) = { 
    outputEdges = outputEdges :+ edge 
    this 
    } 
} 

然而這引入了可能不需要的可變狀態。另一種類似的方法是使用可變列表,如MutableList。還有一個問題是增加metdos抽象,並讓子類負責爲給定的邊添加新的自己的實例。

0

你可以只使用可變變量。不太好... 重新考慮使用具有長構造函數的案例類。

在這裏你去:

trait Node extends Component{ 
    var label:Int 
    var inputEdges:List[Edge] = List[Edge]() 
    var outputEdges:List[Edge] = List[Edge]() 

    def addInputEdge(edge:Edge) = { 
    inputEdges :+= edge 
    this 
    } 

    def addOutputEdge(edge:Edge) = { 
    outputEdges:+= edge 
    this 
    } 
} 

case class SomeNode(label:Int) extends Node 
相關問題