2013-05-15 66 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 
相关问题